注:这里不阐述spring和aop的一些基本概念和用法,直接进入正题。

流程

  spring所管理的对象大体会经过确定实例化对象类型、推断构造方法创建对象(实例化)、设置属性、初始化等等步骤。在对象初始化阶段,spring为开发者提供了一个beanpostprocessor接口,它会在对象初始化之前和初始化之后被调用(初始化,不是实例化,对应实例化的是instantiationawarebeanpostprocessor接口)。

public interface beanpostprocessor {
	//初始化之前
	object postprocessbeforeinitialization(object bean, string beanname) throws beansexception;
	//初始化之后
	object postprocessafterinitialization(object bean, string beanname) throws beansexception;

}

  在对象初始化之后会调用postprocessafterinitialization方法,该方法返回一个object。如果成功返回了一个对象,那么容器中相应beanname对应的实例就将会是这个对象。

  本文主要分析动态代理,我们着重看annotationawareaspectjautoproxycreator。先来看一下它的继承关系:

  annotationawareaspectjautoproxycreator最终实现了beanpostprocessor接口(也实现了instantiationawarebeanpostprocessor接口),可以看到继承关系比较复杂。当前我们关注的postprocessafterinitialization方法实现在它的父类abstractautoproxycreator中(只保留了部分代码):

public object postprocessafterinitialization(object bean, string beanname) throws beansexception {
		if (bean != null) {
			object cachekey = getcachekey(bean.getclass(), beanname);
			if (!this.earlyproxyreferences.contains(cachekey)) {
				return wrapifnecessary(bean, beanname, cachekey);
			}
		}
		return bean;
	}

  这里主要看看wrapifnecessary方法(只保留了部分代码):

object[] specificinterceptors = getadvicesandadvisorsforbean(bean.getclass(), beanname, null);
		......
		object[] specificinterceptors = getadvicesandadvisorsforbean(bean.getclass(), beanname, null);
		if (specificinterceptors != do_not_proxy) {
			this.advisedbeans.put(cachekey, boolean.true);
			object proxy = createproxy(bean.getclass(), beanname, specificinterceptors, new singletontargetsource(bean));
			this.proxytypes.put(cachekey, proxy.getclass());
			return proxy;
		}
		......
}

  其中核心的是两个方法调用,分别是getadvicesandadvisorsforbean和createproxy。getadvicesandadvisorsforbean会返回一个对象数组,包含aop相关的一些对象,如果是一个普通的不需要代理的对象会返回一个空object数组,也就是do_not_proxy;createproxy方法则是创建代理类。

  先看看getadvicesandadvisorsforbean方法:

protected abstract object[] getadvicesandadvisorsforbean(class<?> beanclass, string beanname, targetsource customtargetsource) throws beansexception;

  getadvicesandadvisorsforbean方法在当前类(abstractautoproxycreator)中是一个抽象方法,由子类abstractadvisorautoproxycreator实现:

public abstract class abstractadvisorautoproxycreator extends abstractautoproxycreator {
	@override
	protected object[] getadvicesandadvisorsforbean(class<?> beanclass, string beanname, targetsource targetsource) {
		list<advisor> advisors = findeligibleadvisors(beanclass, beanname);
		if (advisors.isempty()) {
			return do_not_proxy;
		}
		return advisors.toarray();
	}
}

  代码很清晰,我们进入findeligibleadvisors方法,看方法名也知道它会完成寻找advisor的工作:

protected list<advisor> findeligibleadvisors(class<?> beanclass, string beanname) {
		//寻找advisor
		list<advisor> candidateadvisors = findcandidateadvisors();
		//针对指定的bean,过滤可用的advisor,比如根据注解匹配
		list<advisor> eligibleadvisors = findadvisorsthatcanapply(candidateadvisors, beanclass, beanname);
		extendadvisors(eligibleadvisors);
		if (!eligibleadvisors.isempty()) {
			eligibleadvisors = sortadvisors(eligibleadvisors);
		}
		return eligibleadvisors;
	}

  首先进入findcandidateadvisors方法:

protected list<advisor> findcandidateadvisors() {
		// add all the spring advisors found according to superclass rules.
		list<advisor> advisors = super.findcandidateadvisors();
		// build advisors for all aspectj aspects in the bean factory.
		advisors.addall(this.aspectjadvisorsbuilder.buildaspectjadvisors());
		return advisors;
	}

  我们这里主要看看aspectj的逻辑,所以看看aspectjadvisorsbuilder.buildaspectjadvisors方法(只保留了主要代码):

public list<advisor> buildaspectjadvisors() {
		list<string> aspectnames = null;
		......
		synchronized (this) {
			aspectnames = this.aspectbeannames;
			if (aspectnames == null) {
				//获取所有管理的beanname
				string[] beannames = beanfactoryutils.beannamesfortypeincludingancestors(this.beanfactory, object.class, true, false);
				//遍历每个beanname
				for (string beanname : beannames) {
					//从beanfactory获取class
					class<?> beantype = this.beanfactory.gettype(beanname);
					//检查对应的class是否实现aspect注解
					if (this.advisorfactory.isaspect(beantype)) {
						//说明这个beanname对应的类是一个切面	
						aspectnames.add(beanname);
						aspectmetadata amd = new aspectmetadata(beantype, beanname);
						if (amd.getajtype().getperclause().getkind() == perclausekind.singleton) {
							metadataawareaspectinstancefactory factory =
									new beanfactoryaspectinstancefactory(this.beanfactory, beanname);
							//获取advisor,主要是解析对象中关于aop的注解,比如pointcut
							list<advisor> classadvisors = this.advisorfactory.getadvisors(factory);
							if (this.beanfactory.issingleton(beanname)) {
								//就放入缓存,后面就不用重新解析了
								this.advisorscache.put(beanname, classadvisors);
							}
							advisors.addall(classadvisors);
						}
					}
				}
				this.aspectbeannames = aspectnames;
				return advisors;
			}
		}
	......
}

  会从beanfactory中寻找所有管理的beanname,返回一个string数组,然后遍历数组,从beanfactory中根据beanname获取对应的class,然后再看对应的class是否有aspect注解,如果有对应的注解,那么就表示这个对象是一个切面。接下来就需要进行解析,生成真正的advisor对象,最后放入缓存。

  可以看看isaspect方法是如何判断的:

@override
	public boolean isaspect(class<?> clazz) {
		return (hasaspectannotation(clazz) && !compiledbyajc(clazz));
	}
	private boolean hasaspectannotation(class<?> clazz) {
		return (annotationutils.findannotation(clazz, aspect.class) != null);
	}

  逻辑很清晰,主要就是看有没有aspect注解。 但是这里要注意,这个buildaspectjadvisors方法通常不是在这里调用的(”这里“的意思是postprocessafterinitialization的流程)。回到annotationawareaspectjautoproxycreator继承关系图中,它也实现了instantiationawarebeanpostprocessor接口,同样在其父类abstractautoproxycreator中实现了postprocessbeforeinstantiation方法,这个方法会在对象实例化(不是初始化)之前调用,在该方法的逻辑里通常会首先触发buildaspectjadvisors方法的执行,执行之后会把结果缓存起来。

  好了,再回到findeligibleadvisors方法,上面代码已经贴了,这里就不贴了。获取到advisor列表之后,要从中找到能用于指定类的advisor列表,然后返回。接下来就要为指定的对象创建代理对象了,也就是abstractautoproxycreator类的createproxy方法:

	protected object createproxy(
			class<?> beanclass, string beanname, object[] specificinterceptors, targetsource targetsource) {

		proxyfactory proxyfactory = new proxyfactory();
		proxyfactory.copyfrom(this);

		if (!proxyfactory.isproxytargetclass()) {
			if (shouldproxytargetclass(beanclass, beanname)) {
				proxyfactory.setproxytargetclass(true);
			}
			else {
				evaluateproxyinterfaces(beanclass, proxyfactory);
			}
		}

		advisor[] advisors = buildadvisors(beanname, specificinterceptors);
		for (advisor advisor : advisors) {
			proxyfactory.addadvisor(advisor);
		}

		proxyfactory.settargetsource(targetsource);
		customizeproxyfactory(proxyfactory);

		proxyfactory.setfrozen(this.freezeproxy);
		if (advisorsprefiltered()) {
			proxyfactory.setprefiltered(true);
		}

		return proxyfactory.getproxy(getproxyclassloader());
	}

  代理对象是由proxyfactory代理工厂创建的,我们先看看这个工厂是如何创建代理对象的,也就是proxyfactory.getproxy方法:

public object getproxy(classloader classloader) {
	return createaopproxy().getproxy(classloader);
}

  createaopproxy方法会返回一个aopproxy,该方法定义在proxyfactory的父类proxycreatorsupport中:

public class proxycreatorsupport extends advisedsupport {
	private aopproxyfactory aopproxyfactory;
	public proxycreatorsupport() {
		//设置默认的代理工厂defaultaopproxyfactory
		this.aopproxyfactory = new defaultaopproxyfactory();
	}
	public aopproxyfactory getaopproxyfactory() {
		//获取代理工厂,默认就是defaultaopproxyfactory
		return this.aopproxyfactory;
	}

	protected final synchronized aopproxy createaopproxy() {
		//先获取代理工厂,然后调用工厂的createaopproxy方法创建aopproxy
		return getaopproxyfactory().createaopproxy(this);
	}
}

  上面贴出了关键代码,getaopproxyfactory默认返回的是一个defaultaopproxyfactory工厂类,来看看defaultaopproxyfactory的createaopproxy方法:

public aopproxy createaopproxy(advisedsupport config) throws aopconfigexception {
		if (config.isoptimize() || config.isproxytargetclass() || hasnousersuppliedproxyinterfaces(config)) {
			class<?> targetclass = config.gettargetclass();
			if (targetclass.isinterface()) {
				return new jdkdynamicaopproxy(config);
			}
			return new objenesiscglibaopproxy(config);
		}
		else {
			return new jdkdynamicaopproxy(config);
		}
	}

  代码中有一些代理配置的判断,这里不用关心。可以看到它提供了两个aopproxy,分别是基于jdk的jdkdynamicaopproxy和基于cglib的objenesiscglibaopproxy。由于jdk提供的动态代理实现最终生成的代理类默认会继承proxy类,实现被代理类实现的接口,因为java是单继承,所以只能通过接口实现,也就限制了要使用jdk提供的动态代理,必须要基于接口。而使用cglib基于字节码的改造则没有这个限制,所以spring提供了这两种方式,根据被代理类的实际情况来选择。

  关于每个aopproxy是如何创建代理类的,这里就先不跟了~

总结

  总的来说,动态代理是实现aop的重要手段,spring提供的动态代理主要依靠其提供的beanpostprocessor,也称之为后置处理器。除了beanpostprocessor之外,还有instantiationawarebeanpostprocessor(也继承了beanpostprocessor),它们会在bean的生命周期的特定阶段被调用,以开放给开发者处理和调整对象的入口或者手段。动态代理依托后置处理器,在后置处理器的逻辑中使用aopproxy创建了被代理对象的代理类,然后代替原有类存入spring的bean工厂中,之后根据beanname获取的实例对象就不再是原对象实例,而是代理类。而aopproxy是由aopproxyfactory接口生成,目前该接口只有defaultaopproxyfactory实现类,其提供了两种aopproxy,分别基于原生jdk提供的动态代理和cgib,根据实际情况选择。

到此这篇关于spring源码学习之动态代理实现流程的文章就介绍到这了,更多相关spring动态代理实现内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!