Spring AOP源码解析:二:代理对象的创建

Spring AOP源码解析:二:代理对象的创建

一、代理的类型
众所周知,Spring AOP代理的方式有2种,JDK的动态代理和Cglib的代理,前者必须实现接口,后者可以通过继承的方式实现。

二、AOP抽象
先看一段代码,AbstractAutoProxyCreator类,createProxy方法

	protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
			@Nullable Object[] specificInterceptors, TargetSource targetSource) {

		if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
			AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
		}
		// 通过ProxyFactory来创建代理对象。
		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);
		// 要设置增强
		proxyFactory.addAdvisors(advisors);
		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);

		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}
		
		return proxyFactory.getProxy(getProxyClassLoader());
	}

从上面代码我们看到了ProxyFactory这个类是创建代理对象的核心。
Spring AOP源码解析:二:代理对象的创建
首先看Advised接口,官方文档说明,存储了一些关于AOP代理工厂的一些配置,包括拦截器和增强代理接口等等。

  • Interface to be implemented by classes that hold the configuration
  • of a factory of AOP proxies. This configuration includes the
  • Interceptors and other advice, Advisors, and the proxied interfaces.

然后看看ProxyFactory的功能,就是生成一个代理对象。然后看ProxyFactory
的父类ProxyCreatorSupport,这里有一个属性AopProxyFactory,这里AopProxyFactory负责生成AopProxy类。然后AopProxy类生成代理对象。
然后看到AdvisedSupport有一个AdvisorChainFactory,这个是用来生成代理的拦截器的,可以想到,我们生成的代理对象中可以会依赖这个。然后还保存了所有的增强Advisors。它的实现类InstantiationModelAwarePointcutAdvisorImpl,类图如下。
Spring AOP源码解析:二:代理对象的创建
先看一下AopProxyFactory的默认实现DefaultAopProxyFactory,

@Override
	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
	//根据配置来看是否使用JDK动态代理还是cglib代理。这里有两个配置项,config.isProxyTargetClass默认配置在AopAutoConfiguration类里。
		if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
			Class<?> targetClass = config.getTargetClass();
			if (targetClass == null) {
				throw new AopConfigException("TargetSource cannot determine target class: " +
						"Either an interface or a target is required for proxy creation.");
			}
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}

下面来看一下JdkDynamicAopProxy
Spring AOP源码解析:二:代理对象的创建
拦截方法的调用旧在invoke方法中,核心代码在


	// Get the interception chain for this method.
	// 根据AdvisedSupport来获取方法的拦截器和Advice,这里最终定位到AdvisorChainFactory接口的DefaultAdvisorChainFactory类的getInterceptorsAndDynamicInterceptionAdvice方法中。
	List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
	
	// Check whether we have any advice. If we don't, we can fallback on direct
	// reflective invocation of the target, and avoid creating a MethodInvocation.
	if (chain.isEmpty()) {
		// We can skip creating a MethodInvocation: just invoke the target directly
		// Note that the final invoker must be an InvokerInterceptor so we know it does
		// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
		Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
		retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
	}
	else {
		// We need to create a method invocation...
		// 封装成一个ReflectiveMethodInvocation对象,然后执行
		invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
		// Proceed to the joinpoint through the interceptor chain.
		retVal = invocation.proceed();
	}

根据AdvisedSupport来获取方法的拦截器和Advice,这里最终定位到AdvisorChainFactory接口的DefaultAdvisorChainFactory类的getInterceptorsAndDynamicInterceptionAdvice方法中。这里根据advisor获取到了Pointcut,它记录了切点的属性,匹配成功后会调用 MethodInterceptor[] interceptors = registry.getInterceptors(advisor);来获取方法拦截器。这里的拦截器就是我们上一篇讲到的AspectJAroundAdvice这种Advice。一个@Around注解对应的一个方法就是一个拦截器。然后把所有的MethodInterceptor封装成一个ReflectiveMethodInvocation,进行调用。ReflectiveMethodInvocation类中会采用责任链的方式来调用chain中的MethodInterceptor.

	public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
			Advised config, Method method, @Nullable Class<?> targetClass) {

		// This is somewhat tricky... We have to process introductions first,
		// but we need to preserve order in the ultimate list.
		AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
		Advisor[] advisors = config.getAdvisors();
		List<Object> interceptorList = new ArrayList<>(advisors.length);
		Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
		Boolean hasIntroductions = null;

		for (Advisor advisor : advisors) {
			if (advisor instanceof PointcutAdvisor) {
				// Add it conditionally.
				// 这里advisor的一个实现类是InstantiationModelAwarePointcutAdvisorImpl
				PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
				// 这里获取了Pointcut,一个实现类是AspectJExpressionPointcut
				if (config.isPreFiltered() || 
			pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
					MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
					boolean match;
					if (mm instanceof IntroductionAwareMethodMatcher) {
						if (hasIntroductions == null) {
							hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
						}
						match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
					}
					else {
						match = mm.matches(method, actualClass);
					}
					if (match) {
					// 如果匹配成功
						MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
						if (mm.isRuntime()) {
							// Creating a new object instance in the getInterceptors() method
							// isn't a problem as we normally cache created chains.
							for (MethodInterceptor interceptor : interceptors) {
								interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
							}
						}
						else {
							interceptorList.addAll(Arrays.asList(interceptors));
						}
					}
				}
			}
			else if (advisor instanceof IntroductionAdvisor) {
				IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
				if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
					Interceptor[] interceptors = registry.getInterceptors(advisor);
					interceptorList.addAll(Arrays.asList(interceptors));
				}
			}
			else {
				Interceptor[] interceptors = registry.getInterceptors(advisor);
				interceptorList.addAll(Arrays.asList(interceptors));
			}
		}

		return interceptorList;
	}

Advice的继承图如下。
Spring AOP源码解析:二:代理对象的创建
Spring AOP源码解析:二:代理对象的创建

封装成ReflectiveMethodInvocation,然后调用,这里目前看起来有点问题,如果一个方法有多个拦截器的话

public Object proceed() throws Throwable {
		//	We start with an index of -1 and increment early.
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}

		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
			// Evaluate dynamic method matcher here: static part will already have
			// been evaluated and found to match.
			InterceptorAndDynamicMethodMatcher dm =
					(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
			Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
			if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
				//匹配成功的话调用拦截器,这里把自己作为参数传进去,我猜测,如果后面还有其他拦截器的话,肯定会再次调用到this.proceed()
				return dm.interceptor.invoke(this);
			}
			else {
				// Dynamic matching failed.
				// Skip this interceptor and invoke the next in the chain.
				return proceed();
			}
		}
		else {
			// It's an interceptor, so we just invoke it: The pointcut will have
			// been evaluated statically before this object was constructed.
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}

小结:
代理对象的创建以及代理对象的方法执行流程参与者一共有:
Advised:实现类:ProxyFactory: 记录了创建AOP代理对象的配置信息,负责创建代理对象,其内部主要逻辑是ProxyCreatorSupport类。
AopProxyFactory:实现类:DefaultAopProxyFactory负责创建可以生成代理具体的代理对象。如JdkDynamicAopProxy。
AopProxy:实现类:JdkDynamicAopProxy:生成的代理对象中存储了AdvisedSupport,AdvisedSupport中存储了所有的Advisor,Advisor中可以获取Pointcut,经过一系列匹配成功后可以获取拦截器方法,这些拦截器就是之前根据不同注解解析出来的一些类似AspectJAroundAdvice这种的Advice。