关于java:七Spring-AOP底层源码分析

3次阅读

共计 4184 个字符,预计需要花费 11 分钟才能阅读完成。

ProxyFactory 的工作原理

ProxyFactory 是一个代理对象生产工厂,在生成代理对象之前须要对代理工厂进行配置。ProxyFactory 在生成代理对象之前须要决定到底是应用 JDK 动静代理还是 CGLIB 技术。

// config 就是 ProxyFactory 对象
// optimize 为 true, 或 proxyTargetClass 为 true, 或用户没有给 ProxyFactory 对象增加 interface
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.");
    }
    // targetClass 是接口,间接应用 Jdk 动静代理
    if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {return new JdkDynamicAopProxy(config);
    }
    // 应用 Cglib
    return new ObjenesisCglibAopProxy(config);
}
else {
    // 应用 Jdk 动静代理
    return new JdkDynamicAopProxy(config);
}

JdkDynamicAopProxy 创立代理对象过程

  1. 获取生成代理对象所须要实现的接口汇合
  2. 获取通过 ProxyFactory.addInterface() 所增加的接口,如果没有通过 ProxyFactory.addInterface() 增加接口,那么则看 ProxyFactory。setTargetClass() 所设置的 targetClass 是不是一个接口,把接口增加到后果汇合中,同时把 SpringProxy、Advised、DecoratingProxy 这几个接口也增加到后果汇合中去。
  3. 确定好要代理的汇合之后,就利用 Proxy.newProxyInstance() 生成一个代理对象。

JdkDynamicAopProxy 创立代理对象执行过程

  1. 如果通过 ProxyFactory.setExposeProxy() 把 exposeProxy 设置为 true,那么则把代理对象设置到一个 ThreadLocal(currentProxy) 中去。
  2. 获取通过 ProxyFactory 所设置的 target,如果设置的是 targetClass,那么 target 将为 null
  3. 依据以后所调用的办法对象寻找 ProxyFactory 中所增加的并匹配的 Advisor,并且把 Advisor 封装为 MethodInterceptor 返回,失去 MethodIntercepter 链叫做 chain
  4. 如果 chain 为空,则字节执行 target 对应的以后办法,如果 target 为 null 会报错
  5. 如果 chain 不为空,则会顺次执行 chain 中的 MethodInterceptor。如果以后 MethodInterceptor 是 MethodBeforeAdviceInterceptor,那么先执行 Advisor 中所 advice 的 before() 办法,而后执行下一个 MethodInterceptor. 如果以后 MethodInterceptor 是 AfterReturningAdviceInterceptor,那么先执行执行下一个 MethodInterceptor。拿到返回值后,再执行 Advisor 中所 advice 的 afterReturning() 办法

ObjenesisCglibAopProxy 创立代理对象过程

  1. 创立 Enhancer
  2. 设置 Enhancer 的 superClass 为通过 ProxyFactory.setTarget() 所设置的对象的类
  3. 设置 Enhancer 的 interfaces 为通过 ProxyFactory.addInterface() 所增加的接口,以及 SpringProxy、Advisor 接口
  4. 设置 Enhancer 的 Callbacks 为 DynamicAdvisedIntercepter
  5. 最初通过 Enhancer 创立一个代理对象

ObjenesisCglibAopProxy 创立的代理对象执行过程

执行过程次要就看 DynamicAdvisedInterceptor 中的实现,执行逻辑和 JdkDynamicAopProxy 中是一样的。

主动代理(autoproxy)性能

“主动代理”示意只须要在 Spring 中增加某个 Bean,这个 Bean 是一个 BeanPostProcessor,那么 Spring 在每创立一个 Bean 时,都会通过这个 BeanPost Processor 的判断,去判断以后正在创立的这个 Bean 是不是须要进行 AOP。

DefaultAdvisorAutoProxyCreator

AbstractAutoProxyCreator 实现了 SmartInstantiationAwareBeanPostProcessor 接口,是一个 BeanPostProcessor

  1. 在某个 Bean 实例化之前,查看该 AbstractAutoProxyCreator 中是不是设置了 CustomTargetSource,如果设置了就查看以后 Bean 是不是须要创立一个 TargetSource,如果须要就会创立一个 TargetSource 对象,而后进行 AOP 创立一个代理对象,并返回该代理对象
  2. 如果某个 Bean 呈现了循环依赖,那么会利用 getEarlyBeanReference() 办法提前进行 AOP
  3. 在某个 Bean 初始化之后,会调用 wrapIfNecessary() 办法进行 AOP
  4. 在这个类中提供了一个形象办法:getAdvicesAndAdvisorsForBean(),示意对于某个 Bean 匹配了哪些 Advices 和 Advisors

AbstractAdvisorAutoProxyCreator 继承了 AbstractAutoProxyCreator,AbstractAdvisorAutoProxyCreator 中实现了 getAdvicesAndAdvisorsForBean() 办法,实现逻辑为:

  1. 调用 findEligibleAdvisors()
  2. 调用 findCandidateAdvisors,失去所有 Advisor 类型的 Bean。按以后正在进行 Bean 的生命周期的 Bean 进行过滤

@EnableAspectJAutoProxy

这个注解次要是增加了一个 AnnotationAwareAspectJAutoProxyCreator 类型的 BeanDefinition。AspectJAwareAdvisorAutoProxyCreator 继承了 AbstractAdvisorAutoProxyCreator,重写了 shouldSkip(Class<?> beanClass, String beanName) 办法,示意某个 bean 需不需要进行 AOP,在 shouldSkip() 办法中:

  1. 拿到所有的 Advisor
  2. 遍历所有的 Advisor,如果以后 bean 是 AspectJPointcutAdvisor,那么则跳过

AnnotationAwareAspectJAutoProxyCreator 继承了 AspectJAwareAdvisorAutoProxyCreator,重写了 findCandidateAdvisors() 办法,它即能够找到 Advisor 类型的 bean,也能把所有 @Aspect 注解标注的类扫描进去并生成 Advisor

注解和源码对应关系

@Before 对应的是 AspectJMethodBeforeAdvice,间接实现 MethodBeforeAdvice,在进行动静代理时会把 AspectJMethodBeforeAdvice 转成 MethodBeforeAdviceInterceptor,也就转变成了 MethodBeforeAdviceInterceptor

  1. 先执行 advice 对应的办法
  2. 再执行 MethodInvocation 的 proceed(),会执行下一个 Interceptor,如果没有下一个 Interceptor 了,会执行 target 对应的办法

@After 对应的是 AspectJAfterAdvice,间接实现了 MethodInterceptor

  1. 先执行 MethodInvocation 的 proceed(),会执行下一个 Interceptor,如果没有下一个 Interceptor 了,会执行 target 对应的办法
  2. 再执行 advice 对应的办法

@Around 对应的是 AspectJAroundAdvice,间接实现了 MethodInterceptor

  1. 间接执行 advice 对应的办法

@AfterThrowing 对应的是 AspectJAfterThrowingAdvice,间接实现了 MethodInterceptor

  1. 先执行 MethodInvocation 的 proceed(),会执行下一个 Interceptor,如果没有下一个 Interceptor 了,会执行 target 对应的办法
  2. 如果下面抛了 Throwable,那么则会执行 advice 对应的办法

@AfterReturning 对应的是 AspectJAfterReturningAdvice,实现了 AfterReturningAdvice,在进行动静代理时会把 AspectJAfterReturningAdvice 转成 AfterReturningAdviceInterceptor,也就转变成了 MethodInterceptor

  1. 先执行 MethodInvocation 的 proceed(),会执行下一个 Interceptor,如果没有下一个 Interceptor 了,会执行 target 对应的办法
  2. 执行下面的办法后失去最终的办法的返回值
  3. 再执行 Advice 对应的办法
正文完
 0