5.aop 源码剖析
2022-04-26 10:40:46 12 举报
spring aop源码分析
作者其他创作
大纲/内容
或者
candidateAdvisors = findCandidateAdvisors()
兼容老版本
initializeBean
封装保存到集合
判断是不是切面类
findAdvisorsThatCanApply
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
methods.sort
@Import({AspectJAutoProxyRegistrar.class})
返回值
JdkDynamicAopProxy#getProxy
Advisor.class
getAdvicesAndAdvisorsForBean
精筛
false
获取所有bean定义
setCurrentProxy
虽然每次创建bean都会解析切面,但实际上后续都是从缓存拿
没有接口
解析Advisor
AbstractAutoProxyCreator#postProcessBeforeInstantiation
遍历解析,剔除掉其它方法只保留通知方法
return new JdkDynamicAopProxy(config)
加入到缓存
所有切面类的通知方法都放到集合
findCandidateAdvisors();
构建缓存
JdkDynamicAopProxy#invoke
wrapIfNecessary
Proxy.newProxyInstance
判断代理是否配置exposeProxy
getAdvisorMethods
获取切面类所有方法排除@Pointcut
ThreadLocal<Object> currentProxy属性赋值代理对象,暴露代理对象
解析切面类
使用@Import实现ImportBeanDefinitionRegistrar接口注册bean定义
true
classAdvisors = this.advisorFactory.getAdvisors(factory);
createAopProxy()
return advisors
① 在创建bean时,第一次调用bean的后置处理器解析切面
是
本身是JDK代理
② 在bean初始之后,调用bean后置处理器创建动态代理(如果需要)
返回代理对象或者bean对象
advisors.addAll(classAdvisors);
注册AnnotationAwareAspectJAutoProxyCreator.class
advisor = getAdvisoradvisors.add(advisor);
递归调用
获取bean的所有方法遍历只要有方法命中advisor的切点表达式
创建动态代理
添加到集合 eligibleAdvisors
createProxy
createAopProxy().getProxy
advisors.isEmpty()
调用执行
底层就是利用bean的后置处理器
buildAspectJAdvisors()
proxyFactory.getProxy
super.findCandidateAdvisors();
初筛
cglib 和 jdk 的区别1、前者继承实现类直接调用方法,后者基于接口创建代理,通过责任链模式最后反射调用。所以前者性能好点。2、前者能重复增强,后者需要配置代理对象暴露
config.isOptimize()
bean后置处理器的调用
按照这个顺序初次排序
List<Object> chain
DO_NOT_PROXY;
this.advised.exposeProxy
config.isProxyTargetClass()
bean是接口
遍历advisor
从缓存中获取已解析的advisors
doCreateBean
提升性能,避免每次解析
利用proxyFactory创建
因为JDK动态代理,本类的方法嵌套调用,不会继续增强。想要增强嵌套的方法,可以通过暴露代理对象,获取代理对象进行方法调用cglib动态代理本身就可以增强,重要区别
创建方法调用对象
动态代理调用
return new ObjenesisCglibAopProxy(config)
advisor全部封装为拦截器统一调用invoke
advisors.toArray();
AbstractAutoProxyCreator#postProcessAfterInitialization
invocation =\t\t\t\t\t\tnew ReflectiveMethodInvocation
@EnableAspectJAutoProxy
AfterThrowing、AfterReturning、After、Before
开始查找
筛选匹配的advisors
!=DO_NOT_PROXY
proxy
sortAdvisors //排序
底层封装
invocation.proceed()
canApply
判断bean是否标记@Aspect
查找实现
0 条评论
下一页