Spring AOP源码解析
2020-12-07 13:57:28 2 举报
Spring AOP概念
作者其他创作
大纲/内容
1、3 是通过MethodIntercepoter直接转换2、4 是通过适配器转换的
获取切面类中所有通知
否isInfrastructureClass
AbstractAutoProxyCreator#postProcessAfterInitialization
createProxyClassAndInstance()
multi剩法
1
ExposeInvocationInterceptor#invoke
JdkDynamicAopProxy
4
add();调用add方法
true
advisors.add(advisor);
最终
从threadLocal中获取
调用基于JDK动态代理
JdkDynamicAopProxy#invoke
AtAfterThrowing异常通知
忽略说明不是通知
doCreateBean
要判断使用哪种动态代理大致可以分为:是否设置了proxyTargetClass=true 为cglib代理是否有接口,有则为jdk代理
没有符合的advisor就不创建代理标记以后也直直接忽略
createBean
当前Bean是否Advice是否Pointcut是否Advisor是否AopInfrastructureBean是否切面
createAopProxy
3
不代理equals方法不代理hashCode方法不代理DecoratingProxy不代理Advised
决定使用哪种动态代理的关键如果配置了 proxy-target-class=\"true\" 后续将创建cglib代理如果有接口就用jdk代理
设置到threadLocal中
findEligibleAdvisors
newProxyInstance()
initializeBean
创建代理
afterException()
* @ASpectJ 注解驱动的切面(注解) Spring2.0
* 经典的基于接口的配置 Spring1.2
满足
LogUtil跟主要业务没有关系的公共代码增强的模块
作者:一角钱技术(公众号:org_yijiaoqian)内容:Spring AOP源码解析
getAdvisorMethods(aspectClass)排除@PointCut注解的方法
getInterceptorsAndDynamicInterceptionAdvice
通知advice
Method
point
事务...
return nullN
未被解析if (aspectNames == null) {
异常
将advice、point、Method、等信息都封装到Advisor
getBean(\"aopBeanName\")获得aop代理的bean
Calculate计算类接口
前置
是否命中方法精筛
createProxy
第三步:AOP — 代理类的调用
new AspectJAfterThrowingAdvice
* 按切点匹配(需要进入aspectj)
canApply
ReflectiveMethodInvocation#proceed
将advice、pointcut等信息解析到Advisor中
从所有通知器中找到和当前Bean匹配的advisors
是否满足创建代理的条件
AopUtils#findAdvisorsThatCanApply
初始化Bean
当前方法是否标注了注解中的任意一个
符合
buildAspectJAdvisors
织入
chain.isEmpty()
wrapIfNecessary
排除有@Pointcut的方法
8
引入Introductions
当获得被代理的bean时实际获取的时动态代理对象
proxyTargetClass=true
已解析的切面类名称缓存
1内置
...
5
AtBefore前置通知
递归出口:调用到了最后一个拦截器
0
是不是被之前的循环依赖创建过proxy?
advisor instanceof IntroductionAdvisor
拿到之前解析切面的时候就已经解析到的advisor.
调用被代理的方法
sub减法
eligibleAdvisors只要上一步添加了符合的通知
第一步:AOP — 切面解析
去类上面查询有没有@Aspect注解
add加法
已经创建过return bean
7异常
2
有接口
提取Aspect类 中所有的Advice方法
SimpleProgramCalculate(进制计算实现)
end
7
解析exposeProxy属性
beanNames
for
返回
AspectJExpressionPointcut
CglibAopProxy
6自置
code
进入beanPostProcessor
NO
抛出异常
真正的创建Bean
3返回
遍历所有beanName,解析除被@Aspect标记的类
如果转换不了空
@Aspect
eligibleAdvisors.add(candidate);
实现
AtAfterReturning返回通知
getAdvicesAndAdvisorsForBean
new AspectJMethodBeforeAdvice
标记为无需增强
aspectName
AtRound环绕通知
Spring AOP 四种实现方式* 注入式AspectJ切面(其实于Spring并无多大的关系,这个就是使用AspectJ这个框架实现AOP编程)
return null 是
已解析的Advisors缓存
执行目标方法add
根据当前bean找到匹配的advisor
6
切面(Aspect):指关注点模块化,这个关注点可能会横切多个对象。事务管理是企业级Java应用中有关横切关注点的例子。在Spring AOP 中,切面可以使用通用类基于模式的方式(schema-based approach)或者在普通类中以@Aspect注解(@AspectJ注解方式)来实现。连接点(Join point):在Spring AOP中,一个连接点总是代表一个方法的执行,其实就代表增强的方法。通知(Advice):在切面的某个特定的连接点上执行的动作。通知有多种类型,包括“around”、“before”、“after”等等。许多AOP框架,包括Spring在内,都是以拦截器做通知模型的,并维护着一个以连接点为中心的拦截器链。目标对象(Target):目标对象指将要被增强的对象。即包含主业务逻辑的类的对象。切点(Pointcut):匹配连接点的断言。通知和切点表达式相关联,并在满足这个切点的连接点上运行(例如,当执行某个特定名称的方法时)。切点表达式如何于连接点匹配是AOP的核心:Spring默认使用AspectJ切点语义。顾问(Advisor):顾问是Advice的一种包装体系,Advisor是Pointcut以及Advice的一个结合,用来管理Advice和Pointcut。应用无需关系。织入(Weaving):将通知切入连接点的过程叫做织入。引入(Introductions):可以将其他接口和实现动态引入到targetClass中。
方法匹配实现大致分为:
没有就转换
expression
new AspectJAroundAdvice
* 按经典aop的advisor匹配器去匹配
循环当前类和类的接口,所以注解标记在接口上也可以的
或者
直接调用
转换效果
ProgramCalculate(进制计算接口)
1. 适配的advice
beanFactory
1. 是否MethodMatcher为True,匹配所有方法
new AspectJAfterAdvice
new AspectJAfterReturningAdvice
findCandidateAdvisors
从缓存中拿
所有的
调用动态代理类的invoke方法
InstantiationModelAwarePointcutAdvisorImpl
自置
是否targetSourcedBeans是否需要忽略的是否aop基建类是否需要跳过
return null;
从容器获取所有类型为Object的beanName
通知的大致两种转换方式:1.通过适配器2.advice本身实现了Intercepter
NiuhCalculate(目标类Target)
最终得到方法返回值
getProxy
AbstractAutoProxyCreator#postProcessBeforeInstantiation
AspectJAfterAdvice#invoke
切面aspect
2. advice 本身实现了Intercepter比如 AspectJAfterThrowingAdvice
会在解析xml的时候解析肯定在这之前就已经解析好了
如果是aop基础Bean或者候选advisor之前以及通过xml解析过则标记无需创建代理
DefaultAdvisorAdapterRegistry#getInterceptors
MethodInvocation oldInvocation = invocation.get();//记录当前正在执行的拦截器invocation.set(mi);try { try { Object retVal; try { font color=\"#b266ff\
before
否
4后置
二选一
AbstractAutowireCapableBeanFactory
ProxyFactory
有
currentInterceptorIndex=-1
advisedBeans是否解析过
5前置
MethodBeforeAdviceInterceptor#invoke
afterReturn()
内置
AfAfter后置通知
super.findCandidateAdvisors()
是否命中类粗筛
div除法
shouldSkip
toBinary
after()
全部转化为拦截器通过责任链模式调用
获取当前的拦截器++currentInterceptorIndex
将提取的结果加入缓存中
不满足创建动态代理的条件return bean
AspectJAfterThrowingAdvice#invoke
第二步:AOP — 匹配
AfterReturningAdviceInterceptor#invoke
后置
* 纯POJO切面(XML) Spring2.0
是否被解析只会解析一次后续缓存
2异常
eligibleAdvisors就能体系当前bean是否需要被增强,决定是否需要创建动态代理
findAspectJAnnotationOnMethod从所有方法中过滤除下列注解
targeClass
缓存有直接返回
0 条评论
下一页