Spring源码之AOP(二)——代理的生成和链式调用

        上文(链接地址:)我们详细讲到了找根据Advice和Pointcu找切面(Adviosr)的过程,现在,切面找到了,接下来就是生成代理和调用增强逻辑。

目录

1. 生成代理

2. 执行代理方法

(1) JDK代理

a. 链式调用

b. @Before增强 

c. @After增强

d. @AfterReturning增强

e. @AfterThrowing增强

f. @Around增强

(2)Cglib代理

3. 总结 


1. 生成代理

        进入AOP的入口方法wrapIfNecessary():

        所属类:org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
		// 如果是false就直接返回
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// Create proxy if we have advice.
		// 找切面的过程(判断当前实例化的bean是否有切面,如果有则将切面返回)*****
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		// 如果有切面,则生成bean的代理
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			// 创建代理,把被代理对象bean的实例封装到SingletonTargetSource中,生成当前实例化bean的代理对象*****
			// 传入的bean是被代理实例,SingletonTargetSource持有了被代理实例的引用(一级缓存单例池中存的就是代理对象)
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			// 将代理对象返回
			return proxy;
		}
		// 没有代理的情况,就是false
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

        我们着重看Object proxy = createProxy(
                    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));        

        这行代码中,SingletonTargetSource持有了原始对象的引用。我们看一下SingletonTargetSource类的组成:

public class SingletonTargetSource implements TargetSource, Serializable {

	/** use serialVersionUID from Spring 1.2 for interoperability. */
	private static final long serialVersionUID = 9031246629662423738L;


	/** Target cached and invoked using reflection. */
	private final Object target;


	@Override
	public Class<?> getTargetClass() {
		return this.target.getClass();
	}

	@Override
	public Object getTarget() {
		return this.target;
	}

     ----省略无关代码---- 

        在我们日常的AOP中,被代理对象就是Bean对象,是由BeanFactory给我们创建出来的,但是Spring AOP中提供了TargetSource机制,可以用来自定义逻辑来创建被代理对象。 

        JDK中实现动态代理是实现InvocationHandler接口,但Spring却是实现TargetSource接口,  SingletonTargetSource 类实现了TargetSource接口。里面有个target属性,它是Object类型,表示目标对象(被代理对象),TargetSource表示被代理对象的来源。

        比如@Lazy注解,当加在属性上时,会产生一个代理对象赋值给这个属性,产生代理对象的代码为:

protected Object buildLazyResolutionProxy(final DependencyDescriptor descriptor, final
@Nullable String beanName) {
    BeanFactory beanFactory = getBeanFactory();
    Assert.state(beanFactory instanceof DefaultListableBeanFactory,
        "BeanFactory needs to be a DefaultListableBeanFactory");
    final DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) beanFactory;
    TargetSource ts = new TargetSource() {
      @Override
      public Class<?> getTargetClass() {
        return descriptor.getDependencyType();
      }
      @Override
      public boolean isStatic() {
        return false;
      }
      @Override
      public Object getTarget() {
        Set<String> autowiredBeanNames = (beanName != null ? new LinkedHashSet<>
(1) : null);
        Object target = dlbf.doResolveDependency(descriptor, beanName,
autowiredBeanNames, null);
        if (target == null) {
          Class<?> type = getTargetClass();
          if (Map.class == type) {
            return Collections.emptyMap();
          }
          else if (List.class == type) {
            return Collections.emptyList();
          }
          else if (Set.class == type || Collection.class == type) {
            return Collections.emptySet();
          }
          throw new
NoSuchBeanDefinitionException(descriptor.getResolvableType(),
              "Optional dependency not present for lazy injection point");
        }
        if (autowiredBeanNames != null) {
          for (String autowiredBeanName : autowiredBeanNames) {
            if (dlbf.containsBean(autowiredBeanName)) {
              dlbf.registerDependentBean(autowiredBeanName, beanName);
            }
          }
        }
        return target;
      }
      @Override
      public void releaseTarget(Object target) {
      }
    };
    ProxyFactory pf = new ProxyFactory();
    pf.setTargetSource(ts);
    Class<?> dependencyType = descriptor.getDependencyType();
    if (dependencyType.isInterface()) {
      pf.addInterface(dependencyType);
    }
    return pf.getProxy(dlbf.getBeanClassLoader());
  }

        这段代码就利用了ProxyFactory生成代理对象,以及使用了TargetSource,当代理对象在执行某个方法时,调用TargetSource的getTarget()方法它会根据属性在Bean工厂找到对应的对象(byType、byName),得到被代理对象,然后调用被代理对象的方法。

        接下来,进入核心方法createProxy():

        所属类:org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator

	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 = new ProxyFactory();
		// 把AnnotationAwareAspectJAutoProxyCreator中的proxyTargetClass、exposeProxy等属性复制到proxyFactory中
		// this就是AnnotationAwareAspectJAutoProxyCreator入口类,(proxyTargetClass设置是JDK(默认false)还是CGLIB代理,exposeProxy设置代理对象是否放到threadLocal)
		proxyFactory.copyFrom(this);
		// 判断是否有接口,如果没有接口,即使设置为JDK,也会使用CGLIB的动态代理
		if (!proxyFactory.isProxyTargetClass()) {
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}
		// 根据之前找到的切面(specificInterceptors)构建Advisor**
		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		// 把Advisor加入到代理工厂
        // 在这里会判断advisors是否存在IntroductionAdvisor,如果存在则把对应的interface添加到proxyFactory中去
		proxyFactory.addAdvisors(advisors);
		// 把targetSource(就是传进来的SingletonTargetSource)加入到代理工厂
		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);
		// freezeProxy这个变量在使用JDK或CGLIB起作用
		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}
		// 获取代理对象****
		return proxyFactory.getProxy(getProxyClassLoader());
	}

        在这里我提一下,ProxyFactory是Spring对JDK和CGLIB两种动态代理技术的封装,表示是创建代理对象的一个工厂,使用起来会比上面的更加方便,例如:

UserService target = new UserService();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(target);
proxyFactory.addAdvice(new MethodInterceptor() {
  @Override
  public Object invoke(MethodInvocation invocation) throws Throwable {
    System.out.println("before...");
    Object result = invocation.proceed();
    System.out.println("after...");
    return result;
  }
});
UserInterface userService = (UserInterface) proxyFactory.getProxy();
userService.test();

        通过ProxyFactory,可以不用关心到底是用cglib还是jdk动态代理,ProxyFactory会帮我们去判断,如果UserService实现了接口,那么ProxyFactory底层就会用jdk动态代理,如果没有实现接
口,就会用cglib技术,上面的代码,就是由于UserService实现了UserInterface接口,所以最后产生的代理对象是UserInterface类型。

        在createProxy()方法最后一行,进入getProxy()方法:

        所属类:org.springframework.aop.framework.ProxyFactory

	public Object getProxy(@Nullable ClassLoader classLoader) {
		// createAopProxy()创建代理方法--->
		return createAopProxy().getProxy(classLoader);
	}
	protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
		// createAopProxy()创建代理对象(JdkDynamicAopProxy或ObjenesisCglibAopProxy)
		return getAopProxyFactory().createAopProxy(this);
	}

         进入createAopProxy()方法

        所属类:org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

	private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);

	@Override
	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		/**
		 * 如果不是在graalvm虚拟机上运行,则采用JDK动态代理;
		 * 如果ProxyFactory的isOptimize为true,Spring认为cglib比jdk效率高;
		 * 或者isTargetClass(表示代理对象是否为类)为true、或者被代理对象没有实现接口、或者只实现了SpringProxy接口,则采用cglib动态代理;
		 * 如果被代理类是接口,或者被代理类已经是JDK动态代理,则只能用JDK动态代理。
		 */
		if (!IN_NATIVE_IMAGE &&
				(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);
		}
	}

        需要注意的是ProxyFactory、创建出来的代理对象JdkDynamicAopProxy、当前实例化的Bean,这三个是一一对应的。

        回到getProxy()方法,以JDK的动态代理为例,进入JdkDynamicAopProxy的getProxy()方法:

	@Override
	public Object getProxy(@Nullable ClassLoader classLoader) {
		if (logger.isTraceEnabled()) {
			logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
		}
		Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
		findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
		// 创建代理实例(classLoader为类加载器;proxiedInterfaces为接口;this实现了InvocationHandler接口,就是JdkDynamicAopProxy)
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}

        返回创建好的代理实例,到此,代理就生成了,大致的过程就是:

        源对象——代理对象——获取目标对象(target)= 源对象

2. 执行代理方法

(1) JDK代理

        在调用被代理对象的方法时,就会进入JdkDynamicAopProxy的invoke()方法:

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object oldProxy = null;
		boolean setProxyContext = false;

		// 先拿到被代理对象
		TargetSource targetSource = this.advised.targetSource;
		Object target = null;

		try {
			// 如果接口中没有定义equals()方法,则直接调用,equals()和hashCode()方法不走代理
			if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
				// The target does not implement the equals(Object) method itself.
				return equals(args[0]);
			}
			else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
				// The target does not implement the hashCode() method itself.
				return hashCode();
			}
			else if (method.getDeclaringClass() == DecoratingProxy.class) {
				// There is only getDecoratedClass() declared -> dispatch to proxy config.
				// 得到代理对象的类型,而不是所实现的接口
				return AopProxyUtils.ultimateTargetClass(this.advised);
			}
			else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
					method.getDeclaringClass().isAssignableFrom(Advised.class)) {
				// Service invocations on ProxyConfig with the proxy config...
				// 也是直接调用Advised接口中的方法,不走代理逻辑,其实就是利用代理对象获取ProxyFactory中的信息
				return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
			}

			Object retVal;
			// 如果ProxyFactory的exposeProxy属性为true,则将代理对象设置到currentProxy这个ThreadLocal中
			if (this.advised.exposeProxy) {
				// Make invocation available if necessary.
				oldProxy = AopContext.setCurrentProxy(proxy);
				setProxyContext = true;
			}

			// Get as late as possible to minimize the time we "own" the target,
			// in case it comes from a pool.
			// 被代理对象和代理类
			target = targetSource.getTarget();
			Class<?> targetClass = (target != null ? target.getClass() : null);

			// Get the interception chain for this method.
			// 代理对象在执行某个方法时,把方法和被代理的类传进去,然后根据方法筛选出匹配的Advisor,并适配成Interceptor****
			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.
				// 如果没有Advice,说明没有代理逻辑,则直接执行对应方法
				Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
				retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
			}
			else {
				// We need to create a method invocation...
				// 把代理类、目标类、方法、参数、代理链传进去,进行代理的增强
				MethodInvocation invocation =
						new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
				// Proceed to the joinpoint through the interceptor chain.
                // 执行MethodInterceptor代理逻辑*****
				retVal = invocation.proceed();
			}

			// Massage return value if necessary.
			Class<?> returnType = method.getReturnType();
			if (retVal != null && retVal == target &&
					returnType != Object.class && returnType.isInstance(proxy) &&
					!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
				// Special case: it returned "this" and the return type of the method
				// is type-compatible. Note that we can't help if the target sets
				// a reference to itself in another returned object.
				retVal = proxy;
			}

        ----省略无关代码----
	}

        进入getInterceptorsAndDynamicInterceptionAdvice()方法:

        所属类:org.springframework.aop.framework.AdvisedSupport

	public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
		// 代理对象在执行某个方法时,会根据当前ProxyFactory中所设置的Advisor根据当前Method再次进行过滤
		MethodCacheKey cacheKey = new MethodCacheKey(method);
		// 注意这个List,表示的就是Advice链
		List<Object> cached = this.methodCache.get(cacheKey);
		if (cached == null) {
			cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
					this, method, targetClass);
			this.methodCache.put(cacheKey, cached);
		}
		return cached;
	}

        进入getInterceptorsAndDynamicInterceptionAdvice()方法:

        所属类:org.springframework.aop.framework.DefaultAdvisorChainFactory

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();
		// 从ProxyFactory中拿到所有设置的Advice(添加时被封装成了DefaultPointcutAdvisor),添加的时候会控制顺序
		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.
				PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
				// 先匹配类
				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) {
						// 如果匹配则将Advisor封装成MethodInterceptor,当前Advisor中的Advice可能就是MethodBeforeAdvice
						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));
						}
					}

					// 最终,interceptorList中存放的是当前正在执行的Method所匹配的MethodInterceptor,
					// 找到Method所匹配的MethodInterceptor后,就会开始调用这些MethodInterceptor,如果是动态的。
				}
			}
			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;
	}

        在这里会通过getClassFilter()匹配类,再通过getMethodMatcher()匹配方法,如果匹配则将Advisor封装成MethodInterceptor数组,当前Advisor中的Advice就是MethodInterceptor,进入getInterceptors()方法:

        所属类:org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry

	public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
		List<MethodInterceptor> interceptors = new ArrayList<>(3);
		Advice advice = advisor.getAdvice();
		if (advice instanceof MethodInterceptor) {
			interceptors.add((MethodInterceptor) advice);
		}
		// 将Advice适配成MethodInterceptor
		for (AdvisorAdapter adapter : this.adapters) {
			if (adapter.supportsAdvice(advice)) {
				interceptors.add(adapter.getInterceptor(advisor));
			}
		}
		if (interceptors.isEmpty()) {
			throw new UnknownAdviceTypeException(advisor.getAdvice());
		}
		return interceptors.toArray(new MethodInterceptor[0]);
	}

        我们看一下DefaultAdvisorAdapterRegistry的构造方法,会注册三个适配器:

	/**
	 * Create a new DefaultAdvisorAdapterRegistry, registering well-known adapters.
	 */
	public DefaultAdvisorAdapterRegistry() {
		registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
		registerAdvisorAdapter(new AfterReturningAdviceAdapter());
		registerAdvisorAdapter(new ThrowsAdviceAdapter());
	}

        以MethodBeforeAdviceAdapter为例,看看该类的结构:

public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {

	private final MethodBeforeAdvice advice;

	public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
		Assert.notNull(advice, "Advice must not be null");
		this.advice = advice;
	}


	@Override
	@Nullable
	public Object invoke(MethodInvocation mi) throws Throwable {
        // 先执行增强方法
		this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
		return mi.proceed();
	}

}

        它实现了MethodInterceptor接口,执行invoke()方法,会先执行增强方法,然后再执行代理链,“火箭传递”过程。同理,再看一下处理异常的适配器类ThrowsAdviceAdapter:

class ThrowsAdviceAdapter implements AdvisorAdapter, Serializable {

	@Override
	public boolean supportsAdvice(Advice advice) {
		return (advice instanceof ThrowsAdvice);
	}

	@Override
	public MethodInterceptor getInterceptor(Advisor advisor) {
		return new ThrowsAdviceInterceptor(advisor.getAdvice());
	}

}

        看看它对应的方法拦截器ThrowsAdviceInterceptor类:

public ThrowsAdviceInterceptor(Object throwsAdvice) {
		Assert.notNull(throwsAdvice, "Advice must not be null");
		this.throwsAdvice = throwsAdvice;

		Method[] methods = throwsAdvice.getClass().getMethods();
		for (Method method : methods) {
			// 方法名必须是afterThrowing,参数个数1个或4个
			// 1个参数:public void afterThrowing(Exception ex)
			// 4个参数:public void afterThrowing(Method method, Object[] args, Object target, Exception ex)
			if (method.getName().equals(AFTER_THROWING) &&
					(method.getParameterCount() == 1 || method.getParameterCount() == 4)) {
				Class<?> throwableParam = method.getParameterTypes()[method.getParameterCount() - 1];
				if (Throwable.class.isAssignableFrom(throwableParam)) {
					// An exception handler to register...
					this.exceptionHandlerMap.put(throwableParam, method);
					if (logger.isDebugEnabled()) {
						logger.debug("Found exception handler method on throws advice: " + method);
					}
				}
			}
		}

		if (this.exceptionHandlerMap.isEmpty()) {
			throw new IllegalArgumentException(
					"At least one handler method must be found in class [" + throwsAdvice.getClass() + "]");
		}
	}

a. 链式调用

        将前面收集好的切面进行循环执行,就是链式调用过程,主要看proceed()方法,匹配成功才执行增强逻辑invoke()方法,如果不匹配则递归调用,执行下一个MethodInterceptor。

        所属类:org.springframework.aop.framework.ReflectiveMethodInvocation

	public Object proceed() throws Throwable {
		// We start with an index of -1 and increment early.
		// currentInterceptorIndex初始值为-1,每调用一个interceptor会+1,当调用最后一个interceptor后就会执行被代理方法invokeJoinpoint()
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}

        // interceptorsAndDynamicMethodMatchers就是拦截器链,通过currentInterceptorIndex循环执行增强方法
		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);

		// 如果当前interceptor是interceptorOrInterceptionAdvice,则先匹配,匹配成功后再调用该interceptor
		// 如果没有匹配,则递归调用proceed()方法,调用下一个interceptor
		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
			// Evaluate dynamic method matcher here: static part will already have
			// been evaluated and found to match.
            // 只有MethodMather的isRuntime()返回true,它的类型才是InterceptorAndDynamicMethodMatcher
			InterceptorAndDynamicMethodMatcher dm =
					(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
			Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
			// 动态匹配,匹配方法、类名和入参,匹配成功才执行增强逻辑invoke()方法
			if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
				return dm.interceptor.invoke(this);
			}
			else {
				// Dynamic matching failed.
				// Skip this interceptor and invoke the next in the chain.
				// 如果不匹配则递归调用,执行下一个MethodInterceptor
				return proceed();
			}
		}
		else {
			// It's an interceptor, so we just invoke it: The pointcut will have
			// been evaluated statically before this object was constructed.
			// 直接调用那三种MethodInterceptor(ThrowsAdviceInterceptor、MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor),传入this,在内部会再次执行proceed()方法进行递归
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}

b. @Before增强 

        @Before注解的方法,invoke()会执行MethodBeforeAdviceInterceptor.invoke()方法:

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
        // 调用完before()方法的增强之后,继续执行后面的增强,会再次调用ReflectiveMethodInvocation.proceed()方法
		return mi.proceed();
	}

         所属类:org.springframework.aop.aspectj.AspectJMethodBeforeAdvice

	// 代理对象执行时就会执行该方法
	@Override
	public void before(Method method, Object[] args, @Nullable Object target) throws Throwable {
		invokeAdviceMethod(getJoinPointMatch(), null, null);
	}

        通过invokeAdviceMethod()方法,最终会调用到AspectJMethodBeforeAdvice.invokeAdviceMethodWithGivenArgs()方法:

	protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
		Object[] actualArgs = args;
		// aspectJAdviceMethod是@Before修饰的方法
		if (this.aspectJAdviceMethod.getParameterCount() == 0) {
			actualArgs = null;
		}
		try {
			// 反射调用aspectJAdviceMethod方法
			ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
			// TODO AopUtils.invokeJoinpointUsingReflection
			// this.aspectInstanceFactory.getAspectInstance()指切面Bean的实例,actualArgs为方法参数,执行对应方法
			return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
		}
      ----省略无关代码---- 

        这样就调用到了@Before注解对应的方法,调用完before的增强之后,继续执行后面的增强,会再次调用ReflectiveMethodInvocation.proceed()方法,把接力棒传下去。看一下调用被代理方法的逻辑invokeJoinpoint():

        所属类:org.springframework.aop.framework.ReflectiveMethodInvocation

	protected Object invokeJoinpoint() throws Throwable {
        // 反射调用被代理方法,入参分别为目标对象,方法、参数
		return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
	}

c. @After增强

        @After注解的增强器AspectJAfterAdvice :

public class AspectJAfterAdvice extends AbstractAspectJAdvice
		implements MethodInterceptor, AfterAdvice, Serializable {

	public AspectJAfterAdvice(
			Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
		super(aspectJBeforeAdviceMethod, pointcut, aif);
	}

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		try {
			return mi.proceed();
		}
		finally {
			invokeAdviceMethod(getJoinPointMatch(), null, null);
		}
	}

        先执行目标方法,增强逻辑是在finally中执行的。

d. @AfterReturning增强

        @AfterReturning的增强器AfterReturningAdviceInterceptor,先进行火炬传递,可能是其他增强方法,如果调用链执行完,就会调到被代理方法,然后才能拿返回值。

public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {

	private final AfterReturningAdvice advice;

	public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
		Assert.notNull(advice, "Advice must not be null");
		this.advice = advice;
	}

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
        // 先调用被代理方法
		Object retVal = mi.proceed();
        // 拿到返回值后进行反射调用
		this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
		return retVal;
	}

        使用场景为:

    @AfterReturning(value = "pc1()", returning = "retVal")
    public void afterReturning(JoinPoint joinPoint, Object retVal) {
        System.out.println("==============AspectAnnotation.afterReturning后置通知 拿返回值=========" + retVal);
    }

e. @AfterThrowing增强

        @AfterThrowing对应的拦截器为AspectJAfterThrowingAdvice,当被代理方法有异常时才会执行被代理方法。

public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice
		implements MethodInterceptor, AfterAdvice, Serializable {

	public AspectJAfterThrowingAdvice(
			Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
		super(aspectJBeforeAdviceMethod, pointcut, aif);
	}

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		try {
			return mi.proceed();
		}
		catch (Throwable ex) {
			if (shouldInvokeOnThrowing(ex)) {
				invokeAdviceMethod(getJoinPointMatch(), null, ex);
			}
			throw ex;
		}
	}

        应用举例:

    @AfterThrowing(value = "pc1()", throwing = "e")
    public void afterThrowing(JoinPoint joinPoint, Throwable e) {
        System.out.println("AspectAnnotation.afterThrowing异常通知 拿异常=========" + e);
    }

f. @Around增强

         @Around注解对应的拦截器类AspectJAroundAdvice,业务中我们一般使用@Around的增强较多,既能前置,又能后置,也能拿返回值,也能处理异常。

public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor, Serializable {

	public AspectJAroundAdvice(
			Method aspectJAroundAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
		super(aspectJAroundAdviceMethod, pointcut, aif);
	}

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		if (!(mi instanceof ProxyMethodInvocation)) {
			throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
		}
		ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
		ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
		JoinPointMatch jpm = getJoinPointMatch(pmi);
		return invokeAdviceMethod(pjp, jpm, null, null);
	}

        使用实例:

    @Around(value = "pc1()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("==============AspectAnnotation.around前置通知=========");
        Object result = joinPoint.proceed();
        System.out.println("==============AspectAnnotation.around后置通知=========");
        return result;
    }

        环绕增强跟其他拦截不同的是,火炬传递的动作需要人为去触发,通过Object result = joinPoint.proceed();以保证增强链的不断执行,但前置、后置等增强,只需定义增强逻辑,Spring会帮我们进行增强逻辑的传递。

(2)Cglib代理

       看完了JdkDynamicAopProxy的代理,再看看CglibAopProxy类的getProxy(java.lang.ClassLoader)方法:

@Override
	public Object getProxy(@Nullable ClassLoader classLoader) {

		try {
			// 被代理的类
			Class<?> rootClass = this.advised.getTargetClass();
			Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

			Class<?> proxySuperClass = rootClass;
			// 如果被代理类已经是cglib生成的代理类
			if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
				// 获取真正的被代理类
				proxySuperClass = rootClass.getSuperclass();
				// 获取被代理类所实现的接口
				Class<?>[] additionalInterfaces = rootClass.getInterfaces();
				for (Class<?> additionalInterface : additionalInterfaces) {
					this.advised.addInterface(additionalInterface);
				}
			}

			// Validate the class, writing log messages as necessary.
			validateClassIfNecessary(proxySuperClass, classLoader);

			// Configure CGLIB Enhancer...
			Enhancer enhancer = createEnhancer();
			if (classLoader != null) {
				enhancer.setClassLoader(classLoader);
				if (classLoader instanceof SmartClassLoader &&
						((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
					enhancer.setUseCache(false);
				}
			}
			// 被代理类,代理类的父类
			enhancer.setSuperclass(proxySuperClass);
			// 代理类额外需要实现的接口
			enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
			enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
			enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
			// 相当于方法拦截器,获取和被代理类所匹配的Advisor
			Callback[] callbacks = getCallbacks(rootClass);
			Class<?>[] types = new Class<?>[callbacks.length];
			for (int x = 0; x < types.length; x++) {
				types[x] = callbacks[x].getClass();
			}


	}

进入 getCallbacks()方法:

private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
		// Parameters used for optimization choices...
		boolean exposeProxy = this.advised.isExposeProxy();
		boolean isFrozen = this.advised.isFrozen();
		boolean isStatic = this.advised.getTargetSource().isStatic();

		// Choose an "aop" interceptor (used for AOP calls).
		// CGLIB产生的代理对象执行代理逻辑会进入到这里
		Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);

		// Choose a "straight to target" interceptor. (used for calls that are
		// unadvised but can return this). May be required to expose the proxy.
		Callback targetInterceptor;
		if (exposeProxy) {
			targetInterceptor = (isStatic ?
					new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
					new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
		}
		else {
			targetInterceptor = (isStatic ?
					new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
					new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
		}

		// Choose a "direct to target" dispatcher (used for
		// unadvised calls to static targets that cannot return this).
		Callback targetDispatcher = (isStatic ?
				new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());

		Callback[] mainCallbacks = new Callback[] {
				aopInterceptor,  // for normal advice
				targetInterceptor,  // invoke target without considering advice, if optimized
				new SerializableNoOp(),  // no override for methods mapped to this
				targetDispatcher, this.advisedDispatcher,
				new EqualsInterceptor(this.advised),
				new HashCodeInterceptor(this.advised)
		};

		Callback[] callbacks;

		// If the target is a static one and the advice chain is frozen,
		// then we can make some optimizations by sending the AOP calls
		// direct to the target using the fixed chain for that method.
		if (isStatic && isFrozen) {
			Method[] methods = rootClass.getMethods();
			Callback[] fixedCallbacks = new Callback[methods.length];
			this.fixedInterceptorMap = new HashMap<>(methods.length);

			// TODO: small memory optimization here (can skip creation for methods with no advice)
			for (int x = 0; x < methods.length; x++) {
				Method method = methods[x];
				List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
				fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
						chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
				this.fixedInterceptorMap.put(method, x);
			}

			// Now copy both the callbacks from mainCallbacks
			// and fixedCallbacks into the callbacks array.
			callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
			System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
			System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
			this.fixedInterceptorOffset = mainCallbacks.length;
		}
		else {
			callbacks = mainCallbacks;
		}
		return callbacks;
	}

        CGLIB产生的代理对象执行代理逻辑会进入到DynamicAdvisedInterceptor类,进去:

private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {

		private final AdvisedSupport advised;

		public DynamicAdvisedInterceptor(AdvisedSupport advised) {
			this.advised = advised;
		}

		@Override
		@Nullable
		public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
			Object oldProxy = null;
			boolean setProxyContext = false;
			Object target = null;
			TargetSource targetSource = this.advised.getTargetSource();
			try {
				if (this.advised.exposeProxy) {
					// Make invocation available if necessary.
					oldProxy = AopContext.setCurrentProxy(proxy);
					setProxyContext = true;
				}
				// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
				target = targetSource.getTarget();
				Class<?> targetClass = (target != null ? target.getClass() : null);
				List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
				Object retVal;
				// Check whether we only have one InvokerInterceptor: that is,
				// no real advice, but just reflective invocation of the target.
				// 如果为空,直接执行目标对象的方法
				if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
					// 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 = methodProxy.invoke(target, argsToUse);
				}
				// 如果不为空,构造出一个方法调用包装类CglibMethodInvocation
				else {
					// We need to create a method invocation...
					retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
				}
				retVal = processReturnType(proxy, target, method, retVal);
				return retVal;
			}
			finally {
				if (target != null && !targetSource.isStatic()) {
					targetSource.releaseTarget(target);
				}
				if (setProxyContext) {
					// Restore old proxy.
					AopContext.setCurrentProxy(oldProxy);
				}
			}
		}

        当调用逻辑进入到这里,会执行intercept()方法,和JDK实现的功能一摸一样~只是代码不同而已。

3. 总结 

        通过一个流程图来加深本节内容理解:        

        总结一下代理对象执行过程:

  1. 在使用ProxyFactory创建代理对象之前,需要ProxyFactory添加Advisor;
  2. 代理对象在执行某个方法时,会把ProxyFactory中的Advisor拿出来和当前正在执行的方法进行匹配筛选;
  3. 把和当前方法匹配的Advisor适配成MethodInterceptor;
  4. 把和当前方法匹配的MethodInterceptor执行链,以及被代理对象、代理对象、代理类、当前Method对象、方法参数封装为MethodInvocation对象;
  5. 调用MethodInvocation的proceed()方法,开始执行各个MethodInterceptor以及被代理对象的对应方法;
  6. 按顺序调用每个MethodInterceptor的invoke()方法,并且会把MethodInvocation对象传入invoke()方法;
  7. 直到执行完最后一个MethodInterceptor,就会调用invokeJoinpoint()方法,从而执行被代理对象的当前方法。

        总之,就是某个需要AOP的类通过Pointcut的ClassFilter和MethodMatcher找到所有匹配的Advisor,然后利用ProxyFactory生成代理对象;代理对象执行方法时,根据当前调用的方法,找到与之相匹配的Advisor,执行对应的Advice逻辑。

猜你喜欢

转载自blog.csdn.net/qq_40213907/article/details/120360431