spring之AOP源码分析下

发布时间:2024年01月07日

目录

ProxyFactory选择cglib或jdk动态代理原理

jdk/cglib代理对象创建过程

JdkDynamicAopProxy

ObjenesisCglibAopProxy

代理对象执行过程

各切面注解对应的MethodInterceptor

@EnableAspectJAutoProxy

AbstractAdvisorAutoProxyCreator

@EnableAspectJAutoProxy与AbstractAdvisorAutoProxyCreator关系

spring中aop原理流程


ProxyFactory选择cglib或jdk动态代理原理

// 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);
}

根据上述代码可以看到选择代理方式的逻辑。如果实现了接口直接走jdk动态代理。

jdk/cglib代理对象创建过程

JdkDynamicAopProxy

1. 在构造JdkDynamicAopProxy对象时,会先拿到被代理对象自己所实现的接口,并且额外的增加SpringProxy、Advised、DecoratingProxy三个接口,组合成一个Class[],并赋值proxiedInterfaces属性。
2. 并且检查这些接口中是否定义了equals()、hashcode()方法。
3. 执行Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this),得到代理对象,JdkDynamicAopProxy作为InvocationHandler,代理对象在执行某个方法时,会进入到JdkDynamicAopProxy的invoke()方法中。

ObjenesisCglibAopProxy

1. 创建Enhancer对象。
2. 设置Enhancer的superClass为通过ProxyFactory.setTarget()所设置的对象的类。
3. 设置Enhancer的interfaces为通过ProxyFactory.addInterface()所添加的接口,以及SpringProxy、Advised、DecoratingProxy接口。
4. 设置Enhancer的Callbacks为DynamicAdvisedInterceptor。
5. 最后创建一个代理对象,代理对象在执行某个方法时,会进入到DynamicAdvisedInterceptor的intercept()方法中。

代理对象执行过程

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()方法,从而执行被代理对象的当前方法。


各切面注解对应的MethodInterceptor

@Before对应的是AspectJMethodBeforeAdvice,在进行动态代理时会把AspectJMethodBeforeAdvice转成MethodBeforeAdviceInterceptor先执行advice对应的方法
再执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法。
@After对应的是AspectJAfterAdvice,直接实现了MethodInterceptor先执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法
再执行advice对应的方法。
@Around对应的是AspectJAroundAdvice,直接实现了MethodInterceptor直接执行advice对应的方法,由@Around自己决定要不要继续往后面调用。
@AfterThrowing对应的是AspectJAfterThrowingAdvice,直接实现了MethodInterceptor先执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法,如果上面抛了Throwable,那么则会执行advice对应的方法。
@AfterReturning对应的是AspectJAfterReturningAdvice,在进行动态代理时会把AspectJAfterReturningAdvice转成AfterReturningAdviceInterceptor先执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法
执行上面的方法后得到最终的方法的返回值,再执行Advice对应的方法。


@EnableAspectJAutoProxy

AbstractAdvisorAutoProxyCreator

DefaultAdvisorAutoProxyCreator的父类是AbstractAdvisorAutoProxyCreator。AbstractAdvisorAutoProxyCreator非常强大以及重要,只要Spring容器中有该类型的Bean,就相当于开启了AOP,AbstractAdvisorAutoProxyCreator实际上就是一个BeanPostProcessor,所以在创建某个Bean时,就会进入到它对应的生命周期方法中,比如:在某个Bean初始化之后,会调用wrapIfNecessary()方法进行AOP,底层逻辑是,AbstractAdvisorAutoProxyCreator会找到所有的Advisor,然后判断当前这个Bean是否存在某个Advisor与之匹配(根据Pointcut),如果匹配就表示当前这个Bean有对应的切面逻辑,需要进行AOP,需要产生一个代理对象。

@EnableAspectJAutoProxy与AbstractAdvisorAutoProxyCreator关系

@EnableAspectJAutoProxy注解主要就是往Spring容器中添加了一个AnnotationAwareAspectJAutoProxyCreator类型的Bean。

? ? ? ? ?AspectJAwareAdvisorAutoProxyCreator继承了AbstractAdvisorAutoProxyCreator,重写了findCandidateAdvisors()方法,AbstractAdvisorAutoProxyCreator只能找到所有Advisor类型的Bean对象,但是AspectJAwareAdvisorAutoProxyCreator除开可以找到所有Advisor类型的Bean对象,还能把@Aspect注解所标注的Bean中的@Before等注解及方法进行解析,并生成对应的Advisor对象。

? ? ? @EnableAspectJAutoProxy注解,其实就是往Spring容器中添加了一个AbstractAdvisorAutoProxyCreator类型的Bean,因此开启了AOP并且会解析@Before等注解生成Advisor,后续会根据Advisor去匹配对应的切面逻辑。


spring中aop原理流程

生成AOP流程位于Bean生命周期中的初始化后,开始进行AOP时:

1. 先判断当前bean是不是要进行aop,比如当前bean的类型是pointcut、advice、advisor等那就不需要进行aop。

2. 筛选出和当前bean匹配的advice和advisor。

3. 基于bean的原始对象和所匹配的advice和advisor创建代理对象,然后返回。

4. 创建代理对象子流程,构造一个ProxyFactory并配置。

5. 生成代理对象子流程,构造一个Enhancer对象,并设置DynamicAdvisedIntercepter为Callback,代理对象执行方法时会经过此处。

6. 代理对象执行方法子流程,根据当前所调用的方法和对应的类筛选对应的Advisor,获取Advisor中的advice,并封装为MethodInterceptor,将得到的所有匹配组合成List<Object>集合。

7. 将上述获得的所有信息组合成CglibMethodInvocation对象。

8. 调用CglibMethodInvocation对象的proceed方法。

9. 开始执行MethodInterceptor,不同类型MethodInterceptor执行逻辑不同。

10.?MethodInterceptor执行完后,会执行被代理对象的对应的方法,也就是具体的业务方法。

文章来源:https://blog.csdn.net/m0_61853556/article/details/135394304
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。