当前位置 : 主页 > 编程语言 > java >

Spring5 AOP——创建AOP动态代理

来源:互联网 收集:自由互联 发布时间:2023-02-04
Spring AOP的总体流程 1、注册解析AOP的服务 2、解析和加载横切逻辑 3、将横切逻辑织入目标Bean中 AnnotationAwareAspectJAutoProxyCreator继承体系图 AnnotationAwareAspectJAutoProxyCreator既实现了SmartInsta

Spring AOP的总体流程

  • 1、注册解析AOP的服务
  • 2、解析和加载横切逻辑
  • 3、将横切逻辑织入目标Bean中

AnnotationAwareAspectJAutoProxyCreator继承体系图

AnnotationAwareAspectJAutoProxyCreator既实现了SmartInstantiationAwareBeanPostProcessor 又实现了BeanFactoryAware。就可以对容器做一些事情。

 

AnnotationAwareAspectJAutoProxyCreator 实现了Order接口,所以先于普通的BeanPostProcessor注册,并对普通BeanPostProcessor也能起作用。

 

AnnotationAwareAspectJAutoProxyCreator 是InstantiationAwareBeanPostProcessor,会在Bean被创建之前,在resolveBeforeInstantiation中被调用。

 

Spring Aop主要是通过AbstractAutoProxyCreator实现的BeanPostProcessor、InstantiationAwareBeanPostProcessor以及SmartInstantiationAwareBeanPostProcessor接口里面的后置处理器方法,来介入到Spring IOC容器的Bean的实例化以及初始化的过程中对Bean进行AOP的处理的。

 

所以AbstractAutoProxyCreator类里面的实现的容器级别的后置处理器方法便是介入分析的点:

  • 横切逻辑的加载主要是在AbstractAutoProxyCreator类中的postProcessBeforeInstantiation方法中,该方法是在Bean的实例化之前被调用的。

  • 横切逻辑织入目标Bean中主要是在AbstractAutoProxyCreator类中的postProcessAfterInitialization方法中,该方法是在Bean的实例化之后被调用的。

Spring AOP横切逻辑的织入过程:

在Spring5AOP——AbstractAutoProxyCreator横切逻辑织入目标Bean中文章中,分析了横切逻辑织入目标Bean中,本文就分析AbstractAutoProxyCreator类中wrapIfNecessary方法中的createProxy方法,创建AOP动态代理。

wrapIfNecessary

  • 判断当前bean是否需要被代理,如果需要则创建动态代理类。
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware { /** * Spring实现Bean代理的核心方法。wrapIfNecessary在两处会被调用,一处是getEarlyBeanReference, * 另一处是postProcessAfterInitialization */ protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { //已经被处理过 // 1.判断当前bean是否在targetSourcedBeans缓存中存在(已经处理过),如果存在,则直接返回当前bean if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } //不需要被织入逻辑的 // 2.在advisedBeans缓存中存在,并且value为false,则代表无需处理 if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } //是不是基础的bean 是不是需要跳过的 // 3.bean的类是aop基础设施类 || bean应该跳过,则标记为无需处理,并返回 if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // Create proxy if we have advice. // 返回匹配当前Bean的所有Advice\Advisor\Interceptor Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); // 5.如果存在增强器则创建代理 if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); //创建Bean对应的代理,SingletonTargetSource用于封装实现类的信息 // 5.1 创建代理对象:这边SingletonTargetSource的target属性存放的就是我们原来的bean实例(也就是被代理对象), // 用于最后增加逻辑执行完毕后,通过反射执行我们真正的方法时使用(method.invoke(bean, args)) Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); // 5.2 创建完代理后,将cacheKey -> 代理类的class放到缓存 this.proxyTypes.put(cacheKey, proxy.getClass()); // 返回代理对象 return proxy; } //该Bean是不需要进行代理的,下次就不需要重复生成了 this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } }
  • 当执行完getAdvicesAndAdvisorsForBean方法之后,就可以从候选的Advisor列表里筛选出匹配于当前Bean的Advisor列表,获取到Advisor列表之后就会接着执行后续的创建动态代理的步骤了。

  • 由于getAdvicesAndAdvisorsForBean筛选出匹配的Advisor了,将该Bean对应的cacheKey写入到advisedBeans中,并将对应的值设置为true,表示对该Bean进行过Spring AOP的处理了。

  • 之后就会调用createProxy方法去创建目标代理对象实例,创建好动态代理实例之后,就会动态代理实例类型给保存到proxyTypes的缓存里面,并将动态代理实例返回,这样就完成了wrapIfNecessary方法的执行。

  • 如果没有getAdvicesAndAdvisorsForBean没有筛选出匹配的Advisor的话,就证明该Bean不需要织入横切逻辑,此时就会在advisedBeans里给该Bean设置对应的cacheKey和false,以表明该bean是不需要被织入的。

本文重点分析createProxy方法——创建AOP动态代理

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware { protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) { //如果beanFactory是ConfigurableListableBeanFactory的类型,暴露目标类 if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); } //创建一个ProxyFactory,当前ProxyCreator在创建代理时将需要用到的字段赋值到ProxyFactory中去 ProxyFactory proxyFactory = new ProxyFactory(); //将 当前的AnnotationAwareAspectJAutoProxyCreator 对象的属性赋值给ProxyFactory对象 proxyFactory.copyFrom(this); // 处理 proxyTargetClass 属性 // 如果希望使用 CGLIB 来代理接口,可以配置 // proxy-target-class="true",这样不管有没有接口,都使用 CGLIB 来生成代理: // <aop:config proxy-target-class="true"></aop:config> if (!proxyFactory.isProxyTargetClass()) { // 检查preserveTargetClass属性,判断beanClass是应该基于类代理还是基于接口代理 if (shouldProxyTargetClass(beanClass, beanName)) { // 如果是基于类代理,则将proxyTargetClass赋值为true proxyFactory.setProxyTargetClass(true); } else { // 评估bean的代理接口 // 1. 有接口的,调用一次或多次:proxyFactory.addInterface(ifc); // 2. 没有接口的,调用:proxyFactory.setProxyTargetClass(true); evaluateProxyInterfaces(beanClass, proxyFactory); } } // 这个方法主要来对前面传递进来的横切逻辑实例进行包装 // 注意:如果 specificInterceptors 中有 Advice 和 Interceptor,它们也会被包装成 Advisor // 方法会整理合并得到最终的advisors (毕竟interceptorNames还指定了一些拦截器的) // 至于调用的先后顺序,通过方法里的applyCommonInterceptorsFirst参数可以进行设置, // 若applyCommonInterceptorsFirst为true,interceptorNames属性指定的Advisor优先调用。默认为true Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); // 将advisors添加到proxyFactory proxyFactory.addAdvisors(advisors); // 设置要代理的类,将targetSource赋值给proxyFactory的targetSource属性,之后可以通过该属性拿到被代理的bean的实例 proxyFactory.setTargetSource(targetSource); // 这个方法是交给子类的,子类可以继续去定制此proxyFactory customizeProxyFactory(proxyFactory); // 用来控制proxyFactory被配置之后,是否还允许修改通知。默认值为false(即在代理被配置之后,不允许修改代理类的配置) proxyFactory.setFrozen(this.freezeProxy); // 设置preFiltered的属性值,默认是false。子类:AbstractAdvisorAutoProxyCreator修改为true // preFiltered字段意思为:是否已为特定目标类筛选Advisor // 这个字段和DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice获取所有的Advisor有关 //CglibAopProxy和JdkDynamicAopProxy都会调用此方法,然后递归执行所有的Advisor if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } // 使用proxyFactory获取代理 return proxyFactory.getProxy(getProxyClassLoader()); } }

evaluateProxyInterfaces(beanClass, proxyFactory)

  • 根据被代理beanClass是否实现了接口,来评估是调用CGLIB还是JDK动态代理。
public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanClassLoaderAware, AopInfrastructureBean { /** * 这里决定了如果目标类没有实现接口直接就是Cglib代理 * 检查给定beanClass上的接口们,并交给proxyFactory处理 */ protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) { // 找到该类实现的所有接口们 Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader()); // 标记:是否有存在合理的接口 boolean hasReasonableProxyInterface = false; for (Class<?> ifc : targetInterfaces) { if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) && ifc.getMethods().length > 0) { hasReasonableProxyInterface = true; break; } } if (hasReasonableProxyInterface) { // Must allow for introductions; can't just set interfaces to the target's interfaces only. //不管接口是否合理,都将其添加进去 for (Class<?> ifc : targetInterfaces) { proxyFactory.addInterface(ifc); } } else { proxyFactory.setProxyTargetClass(true); } } }

buildAdvisors(beanName, specificInterceptors)

  • 对横切逻辑实例进行包装
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware { protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) { // Handle prototypes correctly... // 解析interceptorNames而来得Advisor数组 Advisor[] commonInterceptors = resolveInterceptorNames(); List<Object> allInterceptors = new ArrayList<>(); if (specificInterceptors != null) { // 添加参数传进来的,即前面解析出来的advisors allInterceptors.addAll(Arrays.asList(specificInterceptors)); if (commonInterceptors.length > 0) { // 添加拦截器 //调用的先后顺序,通过applyCommonInterceptorsFirst参数可以进行设置, // 若applyCommonInterceptorsFirst为true,interceptorNames属性指定的Advisor优先调用。 // 默认为true if (this.applyCommonInterceptorsFirst) { allInterceptors.addAll(0, Arrays.asList(commonInterceptors)); } else { allInterceptors.addAll(Arrays.asList(commonInterceptors)); } } } if (logger.isTraceEnabled()) { int nrOfCommonInterceptors = commonInterceptors.length; int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0); logger.trace("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors + " common interceptors and " + nrOfSpecificInterceptors + " specific interceptors"); } //把拦截器包装为Advisor Advisor[] advisors = new Advisor[allInterceptors.size()]; for (int i = 0; i < allInterceptors.size(); i++) { // wrap包装 advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i)); } return advisors; } }

resolveInterceptorNames

  • 解析interceptorNames而来得Advisor数组
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware { private Advisor[] resolveInterceptorNames() { BeanFactory bf = this.beanFactory; ConfigurableBeanFactory cbf = (bf instanceof ConfigurableBeanFactory ? (ConfigurableBeanFactory) bf : null); List<Advisor> advisors = new ArrayList<>(); for (String beanName : this.interceptorNames) { if (cbf == null || !cbf.isCurrentlyInCreation(beanName)) { Assert.state(bf != null, "BeanFactory required for resolving interceptor names"); Object next = bf.getBean(beanName); advisors.add(this.advisorAdapterRegistry.wrap(next)); } } return advisors.toArray(new Advisor[0]); } }

wrap

  • this.advisorAdapterRegistry.wrap(next)
  • 将满足不是正在创建中的横切逻辑实例,给统一转换成Advisor
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable { @Override public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException { //如果已经是Advisor,则无需多做处理 if (adviceObject instanceof Advisor) { return (Advisor) adviceObject; } if (!(adviceObject instanceof Advice)) { //必须是Advice类型 throw new UnknownAdviceTypeException(adviceObject); } Advice advice = (Advice) adviceObject; if (advice instanceof MethodInterceptor) { // So well-known it doesn't even need an adapter. //如果是MethodInterceptor,则直接使用DefaultPointcutAdvisor进行包装 return new DefaultPointcutAdvisor(advice); } // 否则遍历注册的适配器,如果存在支持的适配器则使用 DefaultPointcutAdvisor 进行包装 //BeforeAdvice、AfterAdvice、ThrowsAdvice三种通知类型的支持是借助适配器模式来实现的 //AdvisorAdapterRegistry,DefaultAdvisorAdapterRegistry和GlobalAdvisorAdapterRegistry //主要负责对AdvisorAdapter进行注册 for (AdvisorAdapter adapter : this.adapters) { // Check that it is supported. if (adapter.supportsAdvice(advice)) { return new DefaultPointcutAdvisor(advice); } } throw new UnknownAdviceTypeException(advice); } }
  • 接着回到createProxy方法中,在执行完buildAdvisors方法之后,就能获取到所有的适配于被代理Bean的Advisor列表,

proxyFactory.getProxy

  • 使用proxyFactory获取代理
public class ProxyFactory extends ProxyCreatorSupport { public Object getProxy(@Nullable ClassLoader classLoader) { // 首先获取AopProxy对象,其主要有两个实现:JdkDynamicAopProxy和ObjenesisCglibAopProxy, // 分别用于Jdk和Cglib代理类的生成,其getProxy()方法则用于获取具体的代理对象 // 1.createAopProxy:创建AopProxy // 2.getProxy(classLoader):获取代理对象实例 return createAopProxy().getProxy(classLoader); } }

createAopProxy()

  • 首先获取AopProxy对象,其主要有两个实现:JdkDynamicAopProxy和ObjenesisCglibAopProxy
public class ProxyCreatorSupport extends AdvisedSupport { protected final synchronized AopProxy createAopProxy() { //主要是为了激活AdvisedSupportListener监听器 if (!this.active) { activate(); } // 2.创建AopProxy return getAopProxyFactory().createAopProxy(this); } }

getAopProxyFactory()

  • 获取AopProxyFactory
public class ProxyCreatorSupport extends AdvisedSupport { private AopProxyFactory aopProxyFactory; public ProxyCreatorSupport() { this.aopProxyFactory = new DefaultAopProxyFactory(); } protected final synchronized AopProxy createAopProxy() { //主要是为了激活AdvisedSupportListener监听器 if (!this.active) { activate(); } // 2.创建AopProxy return getAopProxyFactory().createAopProxy(this); } public AopProxyFactory getAopProxyFactory() { return this.aopProxyFactory; } }

createAopProxy

  • createAopProxy(this)
  • 创建AopProxy
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable { @Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { // 1.判断使用JDK动态代理还是Cglib代理 // optimize:用于控制通过cglib创建的代理是否使用激进的优化策略。除非完全了解AOP如何处理代理优化, // 否则不推荐使用这个配置,目前这个属性仅用于cglib代理,对jdk动态代理无效 // proxyTargetClass:默认为false,设置为true时,强制使用cglib代理,设置方式:<aop:aspectj-autoproxy proxy-target-class="true" /> // hasNoUserSuppliedProxyInterfaces:config是否存在代理接口或者只有SpringProxy一个接口 if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { // 拿到要被代理的对象的类型 Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { // TargetSource无法确定目标类:代理创建需要接口或目标。 throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } // 要被代理的对象是接口 || targetClass是Proxy class 已经是个JDK的代理类(Proxy的子类,所有的JDK代理类都是此类的子类) // 当且仅当使用getProxyClass方法或newProxyInstance方法动态生成指定的类作为代理类时,才返回true。 if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { // JDK动态代理,这边的入参config(AdvisedSupport)实际上是ProxyFactory对象 // 具体为:AbstractAutoProxyCreator中的proxyFactory.getProxy发起的调用,在ProxyCreatorSupport使用了this作为参数, // 调用了的本方法,这边的this就是发起调用的proxyFactory对象,而proxyFactory对象中包含了要执行的的拦截器 return new JdkDynamicAopProxy(config); } // Cglib代理 return new ObjenesisCglibAopProxy(config); } else { // JDK动态代理 return new JdkDynamicAopProxy(config); } } /** * 判断是否有实现自定义的接口 */ private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) { Class<?>[] ifcs = config.getProxiedInterfaces(); return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0]))); } }
  • 这边创建 AopProxy 的参数 config(AdvisedSupport)实际上是proxyFactory 对象。

  • 具体为:AbstractAutoProxyCreator 中的 proxyFactory.getProxy 发起的调用,在 ProxyCreatorSupport 使用了 this 作为参数调用了本方法,这边的 this 就是发起调用的 proxyFactory对象,而 proxyFactory 对象中包含了要执行的的拦截器(Advisor)。

  • 无论是创建 JDK 动态代理还是 CGLIB 代理,都会传入 config 参数,该参数会被保存在 advised(AdvisedSupport)变量中。

JDK 动态代理、CBLIB 代理构造函数

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable { public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException { Assert.notNull(config, "AdvisedSupport must not be null"); if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) { throw new AopConfigException("No advisors and no TargetSource specified"); } this.advised = config; } } class ObjenesisCglibAopProxy extends CglibAopProxy { public ObjenesisCglibAopProxy(AdvisedSupport config) { super(config); } } class CglibAopProxy implements AopProxy, Serializable { public CglibAopProxy(AdvisedSupport config) throws AopConfigException { Assert.notNull(config, "AdvisedSupport must not be null"); if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) { throw new AopConfigException("No advisors and no TargetSource specified"); } this.advised = config; this.advisedDispatcher = new AdvisedDispatcher(this.advised); } }

getProxy(classLoader)

  • 获取代理对象实例

JdkDynamicAopProxy#getProxy

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable { @Override public Object getProxy(@Nullable ClassLoader classLoader) { if (logger.isTraceEnabled()) { logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource()); } // 1.拿到要被代理对象的所有接口 Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true); findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); // 2.通过classLoader、接口、InvocationHandler实现类,来获取到代理对象 return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); } }

最终,通过 JDK 动态代理的类被调用时,会走到 JdkDynamicAopProxy#invoke 方法。

JdkDynamicAopProxy#invoke

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable { @Override @Nullable 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方法不需要代理 if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) { // The target does not implement the equals(Object) method itself. return equals(args[0]); } //若是hashCode方法不需要代理 else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) { // The target does not implement the hashCode() method itself. return hashCode(); } // 如果当前方法是Spring织入的DecoratingProxy接口中的方法,则返回目标对象的Class类型 else if (method.getDeclaringClass() == DecoratingProxy.class) { // There is only getDecoratedClass() declared -> dispatch to proxy config. return AopProxyUtils.ultimateTargetClass(this.advised); } //如果被代理的对象本身就实现了Advised接口,则证明该类里面的方法已经被代理了,直接执行即可 else if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) { // Service invocations on ProxyConfig with the proxy config... return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args); } Object retVal; //是否将动态代理暴露给AopContext 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. //把aop的advisor转化为拦截器链 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. // chain 是空的,说明不需要被织入横切逻辑,直接执行被代理的方法实例本身 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. 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; } else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) { // 如果返回值满足其为空,不是Void类型,并且是基本数据类型,那么就抛出异常, // 因为基本数据类型的返回值必然不为空 throw new AopInvocationException( "Null return value from advice does not match primitive return type for: " + method); } return retVal; } finally { if (target != null && !targetSource.isStatic()) { // Must have come from TargetSource. // 如果TargetSource不是静态的, // 则调用其releaseTarget()方法将生成的目标对象释放 targetSource.releaseTarget(target); } if (setProxyContext) { // Restore old proxy. // 处理AopContext中保存的当前代理对象 AopContext.setCurrentProxy(oldProxy); } } } }

getInterceptorsAndDynamicInterceptionAdvice

  • List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass)
  • 把aop的advisor转化为拦截器链
public class AdvisedSupport extends ProxyConfig implements Advised { /** * 将之前注入到advisorChain中的advisors转换为MethodInterceptor * 和InterceptorAndDynamicMethodMatcher集合 */ public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) { MethodCacheKey cacheKey = new MethodCacheKey(method); //尝试从缓存获取 List<Object> cached = this.methodCache.get(cacheKey); if (cached == null) { //缓存没有,则尝试通过advisorChainFactory去创建调用链 cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice( this, method, targetClass); //将获取到的结果加入到缓存中 this.methodCache.put(cacheKey, cached); } return cached; } }

可以看出上面方法用到缓存的,假设现在缓存没有相应的拦截器, 则到 AdvisorChainFactory 的相应方法中获取,继续跟踪AdvisorChainFactory,进入DefaultAdvisorChainFactory中的相应方法,比较长。

getInterceptorsAndDynamicInterceptionAdvice

  • cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(this, method, targetClass)
  • 缓存没有,则尝试通过advisorChainFactory去创建调用链。
public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable { @Override 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. //通过单例方式实例一个DefaultAdvisorAdapterRegistry // 拿到代理里面所有的通知们:getAdvisors 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. PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor; if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) { //已预过滤过的或者这个切点适用于给定的接口或目标类 //从registry获取MethodInterceptor拦截器 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 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; } private static boolean hasMatchingIntroductions(Advisor[] advisors, Class<?> actualClass) { for (Advisor advisor : advisors) { if (advisor instanceof IntroductionAdvisor) { IntroductionAdvisor ia = (IntroductionAdvisor) advisor; if (ia.getClassFilter().matches(actualClass)) { return true; } } } return false; } }

如果aop的advisor转化为拦截器链为空,说明不需要被织入横切逻辑,直接执行被代理的方法实例本身。

###invokeJoinpointUsingReflection

  • 目标对象方法的调用
  • AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse)
  • 其实是通过AopUtils的方法调用,使用反射机制来对目标对象的方法进行的。
public abstract class AopUtils { @Nullable public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args) throws Throwable { // Use reflection to invoke the method. // 通过反射机制来获得相应的方法,并调用invoke try { ReflectionUtils.makeAccessible(method); return method.invoke(target, args); } catch (InvocationTargetException ex) { // Invoked method threw a checked exception. // We must rethrow it. The client won't see the interceptor. throw ex.getTargetException(); } catch (IllegalArgumentException ex) { throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" + method + "] on target [" + target + "]", ex); } catch (IllegalAccessException ex) { throw new AopInvocationException("Could not access method [" + method + "]", ex); } } }

如果aop的advisor转化为拦截器链不为空,获取目标对象的调用链逻辑,并且对该链进行调用。

  • 如果存在拦截器,则创建一个 ReflectiveMethodInvocation,代理对象、被代理对象、方法、参数、被代理对象的 Class、拦截器链作为参数。这边 ReflectiveMethodInvocation 已经持有了被代理对象、方法、参数,后续就可以直接使用反射来调用被代理的方法了。

ReflectiveMethodInvocation 构造函数

public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable { protected ReflectiveMethodInvocation( Object proxy, @Nullable Object target, Method method, @Nullable Object[] arguments, @Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) { this.proxy = proxy; this.target = target; this.targetClass = targetClass; this.method = BridgeMethodResolver.findBridgedMethod(method); this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments); this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers; } } // 获取目标对象的调用链逻辑,并且对该链进行调用 MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); retVal = invocation.proceed();

ReflectiveMethodInvocation#proceed() 拦截器方法执行

  • 看看拦截器对象,即ReflectiveMethodInvocation中proceed()方法的调用,
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable { @Override @Nullable public Object proceed() throws Throwable { // We start with an index of -1 and increment early. // 注意这里是递归调用,所以是从索引为-1的拦截器开始调用,并按序递增 //如果拦截器链中的拦截器调用完毕,就执行被代理的方法本身 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { //执行目标方法 return invokeJoinpoint(); } //获取第一个方法拦截器使用的是前++,获取下一个要执行的拦截器 //每递归调用一次,currentInterceptorIndex加一。 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)) { //递归调用 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); } } }

该方法是一个责任链的方法,会按索引执行所有的拦截器。

  • 如果所有拦截器都执行完毕(index是从-1开始,所以跟size - 1比较),则直接使用反射调用连接点(也就是我们原本的方法)。

  • MethodBeforeAdviceInterceptor 前置通知

  • AspectJAfterAdvice 后置通知

  • AfterReturningAdviceInterceptor 返回通知

  • AspectJAfterThrowingAdvice 异常通知

以上拦截器方法都在invoke()方法中执行

递归调用拦截器

invokeJoinpoint 执行目标方法

public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable { @Nullable protected Object invokeJoinpoint() throws Throwable { // 反射执行连接点,也就是原方法,target为被代理的对象实例、method为执行的方法、arguments为方法参数 return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments); } } public abstract class AopUtils { @Nullable public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args) throws Throwable { // Use reflection to invoke the method. // 通过反射机制来获得相应的方法,并调用invoke try { ReflectionUtils.makeAccessible(method); return method.invoke(target, args); } catch (InvocationTargetException ex) { // Invoked method threw a checked exception. // We must rethrow it. The client won't see the interceptor. throw ex.getTargetException(); } catch (IllegalArgumentException ex) { throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" + method + "] on target [" + target + "]", ex); } catch (IllegalAccessException ex) { throw new AopInvocationException("Could not access method [" + method + "]", ex); } } }

CglibAopProxy#getProxy

class CglibAopProxy implements AopProxy, Serializable { @Override public Object getProxy(@Nullable ClassLoader classLoader) { if (logger.isTraceEnabled()) { logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource()); } try { // 1.拿到要代理目标类 Class<?> rootClass = this.advised.getTargetClass(); Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy"); // proxySuperClass默认为rootClass Class<?> proxySuperClass = rootClass; // 这里判断rootClass是否是Cglib代理所产生的类(内部判断rootClass的className是否包含$$) // 如果rootClass是被Cglib代理过的,获取rootClass的父类作为proxySuperClass if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) { proxySuperClass = rootClass.getSuperclass(); Class<?>[] additionalInterfaces = rootClass.getInterfaces(); for (Class<?> additionalInterface : additionalInterfaces) { // 将父类的接口也添加到advised的interfaces属性 this.advised.addInterface(additionalInterface); } } // Validate the class, writing log messages as necessary. // 方法校验,final方法不能被代理,记录日志 // 2.校验proxySuperClass,主要是校验方法是否用final修饰、跨ClassLoader的包可见方法,如果有将警告写入日志 validateClassIfNecessary(proxySuperClass, classLoader); // Configure CGLIB Enhancer... // 3.创建和配置Cglib Enhancer Enhancer enhancer = createEnhancer(); if (classLoader != null) { enhancer.setClassLoader(classLoader); if (classLoader instanceof SmartClassLoader && ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) { enhancer.setUseCache(false); } } // superclass为被代理的目标类proxySuperClass,通过名字可以看出,生成的代理类实际上是继承了被代理类 enhancer.setSuperclass(proxySuperClass); enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised)); enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE); enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader)); // 4.获取所有要回调的拦截器 // 通过callbacks设置拦截器链 // spring在这里考虑了很多种情况,将所有callback放到一个数组中。 // 而在某些特定场景下,spring还对回调进行了优化,生成新的回调函数,追加到callbacks数组中。 Callback[] callbacks = getCallbacks(rootClass); Class<?>[] types = new Class<?>[callbacks.length]; for (int x = 0; x < types.length; x++) { types[x] = callbacks[x].getClass(); } // fixedInterceptorMap only populated at this point, after getCallbacks call above // 设置回调过滤器,修正后的拦截器map和偏移量在这里传进去 // 在上面调用getCallbacks之后,此时仅填充fixedInterceptorMap enhancer.setCallbackFilter(new ProxyCallbackFilter( this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset)); enhancer.setCallbackTypes(types); // Generate the proxy class and create a proxy instance. // 生成代理类实例 // 5.生成代理类并创建代理实例,返回代理实例 return createProxyClassAndInstance(enhancer, callbacks); } catch (CodeGenerationException | IllegalArgumentException ex) { throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() + ": Common causes of this problem include using a final class or a non-visible class", ex); } catch (Throwable ex) { // TargetSource.getTarget() failed throw new AopConfigException("Unexpected AOP exception", ex); } } }

getCallbacks

  • 获取所有要回调的拦截器
class CglibAopProxy implements AopProxy, Serializable { private Callback[] getCallbacks(Class<?> rootClass) throws Exception { // Parameters used for optimization choices... // 1.用于优化选择的参数 boolean exposeProxy = this.advised.isExposeProxy(); boolean isFrozen = this.advised.isFrozen(); boolean isStatic = this.advised.getTargetSource().isStatic(); // Choose an "aop" interceptor (used for AOP calls). // 最常用的就是这个拦截器DynamicAdvisedInterceptor // 2.使用AdvisedSupport作为参数,创建一个DynamicAdvisedInterceptor(“aop”拦截器,用于AOP调用) // this.advised就是之前创建CglibAopProxy时传进来的ProxyFactory(ProxyCreatorSupport子类) 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()); // 原始的7种callback // 3.将aop拦截器添加到mainCallbacks中 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. // 如果目标类是不可变的(getTarget()方法返回的对象是否一直是同一个,也就是说对单例对象而言,isStatic都返回true), // 且代理对象被冻结(isFrozen属性设置为true),那么spring将会采取优化,在callbacks数组中增加了新的回调, // 使用修正后的增强链把aop调用直接转发到目标方法来进行一些优化,也就是说此时代理将不生效 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. // 把默认的7种callback和修正后的callback合并到一个数组中返回 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#intercept 方法。

DynamicAdvisedInterceptor#intercept

class CglibAopProxy implements AopProxy, Serializable { 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); // 这里获取拦截器链的方式与jdk动态代理方式调用了同一个方法 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. // chain 是空的,说明不需要被织入横切逻辑,直接执行被代理的方法实例本身 Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); retVal = methodProxy.invoke(target, argsToUse); } 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()方法将生成的目标对象释放 targetSource.releaseTarget(target); } if (setProxyContext) { // Restore old proxy. // 处理AopContext中保存的当前代理对象 AopContext.setCurrentProxy(oldProxy); } } } } }
  • DynamicAdvisedInterceptor#intercept(),该方法中通过List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass)获取一个List拦截链,这里获取拦截器链的方式与上面分析jdk动态代理方式调用了同一个方法。

  • 然后通过retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed()方法执行对应的拦截链进行执行处理。

  • 最后通过processReturnType(proxy, target, method, retVal)处理返回值,并返回。

  • 整体过程完全采用动态代理模式来实现。

CglibMethodInvocation构造函数

class CglibAopProxy implements AopProxy, Serializable { private static class CglibMethodInvocation extends ReflectiveMethodInvocation { @Nullable private final MethodProxy methodProxy; public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method, Object[] arguments, @Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) { super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers); // Only use method proxy for public methods not derived from java.lang.Object this.methodProxy = (Modifier.isPublic(method.getModifiers()) && method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) && !AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method) ? methodProxy : null); } } }

CglibMethodInvocation#proceed()

class CglibAopProxy implements AopProxy, Serializable { private static class CglibMethodInvocation extends ReflectiveMethodInvocation { @Override @Nullable public Object proceed() throws Throwable { try { return super.proceed(); } catch (RuntimeException ex) { throw ex; } catch (Exception ex) { if (ReflectionUtils.declaresException(getMethod(), ex.getClass())) { throw ex; } else { throw new UndeclaredThrowableException(ex); } } } } }

CglibMethodInvocation中的proceed方法最终调用到了ReflectiveMethodInvocation类中的proceed方法,该方法在前面JDK动态代理中解析过。

 

至此,创建 AOP 代理,以及AOP的调用,已经介绍完毕。

总结:

  • 1、@EnableAspectJAutoProxy 会注册一个AnnotationAwareAspectJAutoProxyCreator

  • 2、AnnotationAwareAspectJAutoProxyCreator是一个InstantiationAwareBeanPostProcessor

  • 3、创建流程:

    • A、registerBeanPostProcessors() 注册后置处理器,创建AnnotationAwareAspectJAutoProxyCreator
    • B、finishBeanFactoryInitialization 初始化剩下的单实例Bean
      • a、创建Bean和切面
      • b、AnnotationAwareAspectJAutoProxyCreator拦截创建过程
      • c、创建完Bean判断是否需要增强。通过BeanPostProcessorsAfterInitialization,wrapIfNecessary() 包装代理对象
  • 4、执行目标方法

    • A、获取拦截器链(advisor包装为Interceptor)
    • B、递归调用拦截器链
      • 前置通知、目标方法、后置通知、返回通知、异常通知

参考: https://zhuanlan.zhihu.com/p/104521455

https://segmentfault.com/a/1190000015830477

https://blog.csdn.net/fuli_mouren/article/details/45244453

http://www.mamicode.com/info-detail-890966.html

上一篇:Spring5 MVC——初始化入口分析
下一篇:没有了
网友评论