Spring-AOP源码解析
2020-10-28 17:03:33 0 举报
Spring-AOP源码流程图
作者其他创作
大纲/内容
AfterReturning 3
通知类型 添加时集合的长度
执行
AspectJAfterThrowingAdvice
如果bean实现TargetSource接口,且容器中有TargetSourceCreator,则会通过自定义方式生成代理(一般不会走此流程)
无
afterReturn
空
遍历切面流程
返回Advisor集合
List<Advisor> order(1)
最终么有
After 2
满足其中一条
true
遍历,执行内容
此处采用了dcl检查
此时形成的集合格式
AfterReturning...
2
未找到
通知Advise(before、after都叫通知)
1
从advisorNames=cachedAdvisorBeanNames中获取缓存bean
是
从缓存中获取this.advisorsCache.get(aspectName)
都不满足
createAopProxy判断采用何种方式创建代理
4
InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
是否无接口
AtAfterReturning
启用aspectj自动代理
注册AnnotationAwareAspectJAutoProxyCreator到bean定义中(org.springframework.aop.config.internalAutoProxyCreator)
List<Advisor>
获取自身类型,并加入Set<Class<?>> classes集合中
是否需要忽略的bean
创建当前bean代理代理
Before 1
解析切面获取Advisor集合
LogUtil
切面=LogUtil类,里面包含 before、after
均为连接点
AtPointcut
否,继续遍历
获取通知集合是否为空
before
add
Calculate
是否为引入
获取缓存key
isOptimize 默认false
SmartInstantiationAwareBeanPostProcessor
否
根据方法注解路由,生成对应Advice类型
Around 0
调用
满足其一
获取候选通知集合
第二次遍历通知集合
proxyTargetClass = true
初筛
AnnotationAwareAspectJAutoProxyCreator
获取到
JdkDynamicAopProxy
AspectJAroundAdvice
Advisor对象中属性包括Advice、PointCut等
返回proxy
设置hasReasonableProxyInterface = true
AtAfter
ExposeInvocationInterceptor.ADVISOR
返回空集合
AtBefore
A类名
B类名
将所有Advisor转换为interceptor,chain责任链模式
其他流程
此时形成的Map格式
额外增加一个ExposeInvocationInterceptor
不调用代理类
遍历循环查看类中方法是否有符合切点表达式的方法
判断增强是否与当前类能匹配
earlyProxyReferences在循环依赖中会创建代理对象,放到此Map中,如果有则不再创建
获取切面信息
精筛
后
返回true
是否是AspectJPointcutAdvisor实例,且与当前beanName一致
构建AspectJ切面信息
将当前代理放到threadLocal中
获取切点表达式
Advisor各属性赋值
初筛,根据切点表达式,未指定具体类则会通过
解析的bean是否是Advice、PointCut、Advisor 或者AopInfrastructureBean类型的(判断是不是基础bean)
非空
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Import(AspectJAutoProxyRegistrar.class)public @interface EnableAspectJAutoProxy
有
AfterThrowing 4
返回bean
List<Advisor> order(0)
proxyTargetClass= ?
配合的,排序后格式
1、是否为接口2、是否为代理类
加入通知集合
NULL
afterException
false
排除@PointCut方法,且按照Around->Before->After->AfterReturning->AfterThrowing 排序
调用构造器实例化bean
AspectJMethodBeforeAdvice
AnnotationAwareAspectJAutoProxyCreator父类AbstractAutoProxyCreator的postProcessAfterInitialization
采用jdknew JdkDynamicAopProxy(config)
返回通知集合
//当前的切点信息 this.declaredPointcut = declaredPointcut; //切面的class对象 this.declaringClass = aspectJAdviceMethod.getDeclaringClass(); //切面方法的名称 this.methodName = aspectJAdviceMethod.getName(); //切面方法的参数类型 this.parameterTypes = aspectJAdviceMethod.getParameterTypes(); //切面方法对象 this.aspectJAdviceMethod = aspectJAdviceMethod; //aspectj的通知工厂 this.aspectJAdvisorFactory = aspectJAdvisorFactory; //aspect的实例工厂 this.aspectInstanceFactory = aspectInstanceFactory; //切面的顺序 this.declarationOrder = declarationOrder; //切面的名称 this.aspectName = aspectName;
返回false
AfterThrowing
sub
采用cglibnew ObjenesisCglibAopProxy(config)
创建代理对象
匹配上的连接点为切点
经过一系列筛选条件1、未被处理过2、需要增强的3、是基础bean,不跳过
结束
设置为true
CglibAopProxy
根据beanName获取class对象,判断对象上是@Aspect,且非ajc$开头
对通知集合排序
切入的过程称为织入,通过动态代理实现
最终无匹配
div
advisorNames是否为空
将Advice 、pointcut 封装成 Advisor
@EnableAspectJAutoProxypublic class XXXXConfig
AtAfterThrowing
获取满足当前bean创建代理的通知集合
从bean工厂中获取Advisor类型的bean名称
intercept
this.advised.exposeProxy=true(@EnableAspectJAutoProxy(exposeProxy = true))
AnnotationAwareAspectJAutoProxyCreator父类AbstractAutoProxyCreator的postProcessBeforeInstantiation
earlyProxyReferences中是否存在
@Configuration@EnableAspectJAutoProxy(proxyTargetClass = true)public class MainConfig{}
不满足
未获取
是否为代理类
第一次遍历通知集合
after
基本不会走其他流程
总结:1、设置proxyTargetClass=true,采用cglib2、未设置,且有接口,则采用 jdk
此次从advisorsCache中获取通知集合
是否为PointcutAdvisor类型
获取当前类的所有实现的接口
返回null(不影响bean创建流程)
3
bean创建过程
mul
5
是否设置了proxyTargetClass(表示采用cglib)
找到所有候选切面
AspectJAfterAdvice
是否为IntroductionAdvisor类型
遍历从IOC容器中获取的BeanName集合
AOP概念
是否有接口
如果是FactoryBean,需加&,如&car
7返回
AnnotationAwareAspectJAutoProxyCreator后置处理器的继承图
从缓存获取切面名集合aspectNames = this.aspectBeanNames
生成代理
放到缓存中,标记为未解析
满足
调用invoke方法1、equals2、hashCode3、DecoratingProxy4、Advised子类
BeanPostProcessor
获取切面内所有方法
AtAround
InstantiationAwareBeanPostProcessor
获取IOC容器中所有实现Object的类(即所有bean),筛选合适bean进行解析成advisor集合
执行获取通知集合
收藏
收藏
0 条评论
下一页