Spring之AOP底层源码解析
2022-10-15 15:21:12 1 举报
AOP详解
作者其他创作
大纲/内容
代理对象在执行某个方法时,会进入到JdkDynamicAopProxy#invoke
实例化前InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
实例化,得到原始对象
true/false
当前bean是否Advice是否Pointcut是否Advisor是否AopInfrastructureBean是否解析过的类中有Aspect.class注解
Advisors
构建InstantiationModelAwarePointcutAdvisorImpl对象
如果是pertarget或perthis,则会多生成一个Advisor【SyntheticInstantiationAdvisor】并放在最前面
Proxy.newProxyInstance
JdkDynamicAopProxy#getProxy()
ReflectiveAspectJAdvisorFactory#getPointcut#拿到当前方法所对应的Pointcut对象AspectJExpressionPointcut
初始化后
@AfterThrowing对应的是AspectJAfterThrowingAdvice
创建代理对象
@AfterReturning对应的是AspectJAfterReturningAdvice
再进行精筛
直接new出来一个LazySingletonAspectInstanceFactoryDecorator
@Around对应的是AspectJAroundAdvice
MethodInterceptor
DefaultAopProxyFactory#createAopProxy#创建代理类
获取切面类中没有加@Pointcut的方法,进行遍历生成Advisor
return new ObjenesisCglibAopProxy(config);
true
AbstractAutoProxyCreator#wrapIfNecessary
筛选出和当前bean所匹配的advice和advisor
AfterReturningAdviceInterceptor
BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors#找到所有的Advisors
构建一个ProxyFactory
将代理对象、被代理对象、当前正在执行的被代理类中的方法对象,方法参数,被代理的类,chain、当前正在执行的代理类中的方法对象整合成一个ReflectiveMethodInvocation对象
解析AOP切面
aspectName
利用BeanFactoryAspectInstanceFactory来解析Aspect类ReflectiveAspectJAdvisorFactory#getAdvisors
得到代理对象
否
InstantiationModelAwarePointcutAdvisorImpl
缓存切面所对应的所有Advisor对象
isInfrastructureClass(beanClass)
筛选与当前bena匹配的advisor和adviceAbstractAdvisorAutoProxyCreator#findEligibleAdvisors
如果是aop基础Bean或者候选avisor之前已经通过xml解析过则标记无需创建代理
如果ProxyFactory的isOptimize为true,Spring认为cglib比jdk动态代理要快或者isProxyTargetClass为true,或者被代理对象没有实现接口,或者只实现了SpringProxy这个接口那么则利用Cglib进行动态代理
先判断targetClass是不是和当前Pointcut匹配
初始化
但如果被代理类是接口,或者被代理类已经是进行过JDK动态代理而生成的代理类了则只能进行JDK动态代理其他情况都会进行JDK动态代理,比如被代理类实现了除SpringProxy接口之外的其他接口
如果@Aspect不是perthis、pertarget,那么一个切面只会生成一个对象(单例)
代理对象在执行某个方法时,会进入到DynamicAdvisedInterceptor的intercept()方法中
属性填充
point
在一个代理对象调用方法的时候,就会执行该Advisor,并且会利用lazySingletonAspectInstanceFactory来生成一个切面Bean
把所有beanNames拿出来遍历,判断某个bean的类型是否是Aspect
构建Enhancer对象
先执行advice对应的方法再执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法
1、先执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法2、执行上面的方法后得到最终的方法的返回值3、再执行Advice对应的方法
配置ProxyFactory
调用CglibMethodInvocation对象的proceed方法
AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors#寻找所有的advisor
Bean的生命周期
MethodBeforeAdviceInterceptor
AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
基于原始对象和所匹配的advice和advisor创建代理对象,返回
先找到所有Advisor类型的Bean对象
将得到所有匹配的MethodInterceptor组合成List<Object> chain
在构造JdkDynamicAopProxy对象时,会先拿到被代理对象自己所实现的接口,并且额外的增加SpringProxy、Advised、DecoratingProxy三个接口,组合成一个Class[],并赋值给proxiedInterfaces属性
AbstractAutoProxyCreator#postProcessBeforeInstantiation
设置DynamicUnadvisedInterceptor为callbacks
AopUtils#canApply()
CglibAopProxy#getProxy()
@After对应的是AspectJAfterAdvice
BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors# 再从所有切面中解析得到Advisor对象
AbstractAutoProxyCreator#postProcessAfterInitialization
AbstractAutoProxyCreator#createProxy
执行Interceptors的invoke方法
设置Enhancer的superClass为通过ProxyFactory.setTarget()所设置的对象的类设置Enhancer的interfaces为通过ProxyFactory.addInterface()所添加的接口,以及SpringProxy、Advised、DecoratingProxy接口
先执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法再执行advice对应的方法
初始化后,进行AOP处理
判断被代理的接口中是否定义了equals()、hashCode()方法,如果程序员在接口中手动定义了这两个方法,则也会进行代理// 否则这两个方法是不会走代理逻辑的
直接执行advice对应的方法,由@Around自己决定要不要继续往后面调用
1、先执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法2、如果上面抛了Throwable,那么则会执行advice对应的方法
MethodInterceptor执行完就会执行真正的业务方法
初始化前
new JdkDynamicAopProxy(config);
不代理equals方法不代理hashCode方法不代理DecoratingProxy不代理Advised接口
AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply#进行筛选
Method
AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice
@Before对应的是AspectJMethodBeforeAdvice
false
0 条评论
下一页