[toc]
##使用讲解
-
编写aspect类,并使用@component加入spring的容器
-
aop:aspectj-autoproxy/ 会在spring创建bean的时候应用@Aspect注解的切点和通知
##源码解析
想把所有的@aspect注解的bean 转换成advisor ,然后从中找到匹配当前bean的advosor,创建代理类
入口
AspectJAwareAdvisorAutoProxyCreator是继承与SmartInstantiationAwareBeanPostProcessor接口的,该接口会在创建完bean之后执行postProcessBeforeInstantiation方法,spring容器中实际返回的对象是经过该方法处理后的对象,也就是代理对象,每个bean可能会适配多个切面,spring的处理时将所有的切面转换成拦截器(MethodInteceptor),然后将拦截器生成一个链,按照指定的顺序执行。
-
相关类图
-
启动方法
AbstractAutoProxyCreator.postProcessBeforeInstantiation{}
获取切面 InstantiationModelAwarePointcutAdvisorImpl
查找所有非@PointCut注解的方法,如果方法上面有{Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class}这些注解,则认为这个是一个advice,就会去创建一个切面,通过方法上面注解的切点表达式来创建切点,在创建完之后会统一的缓存下来的(BeanFactoryAspectJAdvisorsBuilder.advisorsCache)。
AbstractAutoProxyCreator.postProcessBeforeInstantiation{}->
AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean{}->
AbstractAdvisorAutoProxyCreator.findEligibleAdvisors{}->
AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors{}->
BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors{}
ReflectiveAspectJAdvisorFactory.getAdvisors(new PrototypeAspectInstanceFactory(this.beanFactory, beanName)){}->
ReflectiveAspectJAdvisorFactory.getAdvisor{}->
new InstantiationModelAwarePointcutAdvisorImpl{}->
切面排序 AspectJPrecedenceComparator
先将所有的切面获取出来,然后筛选出匹配的切面,然后使用AspectJPrecedenceComparator排序切面
AbstractAdvisorAutoProxyCreator.findEligibleAdvisors{}->
AspectJAwareAdvisorAutoProxyCreator.sortAdvisors{}->
new PartiallyComparableAdvisorHolde(new AspectJPrecedenceComparator()){}->
获取pointCut AspectJExpressionPointcut
ReflectiveAspectJAdvisorFactory.getAdvisor{}->
ReflectiveAspectJAdvisorFactory.getPointcut{}->
new AspectJExpressionPointcut{}
###获取advice
(AspectJMethodBeforeAdvice、AspectJAfterAdvice、AspectJAfterReturningAdvice、AspectJAfterThrowingAdvice,AspectJAroundAdvice)
ReflectiveAspectJAdvisorFactory.getAdvisor{}->
new InstantiationModelAwarePointcutAdvisorImpl{}->
InstantiationModelAwarePointcutAdvisorImpl.instantiateAdvice{}->
ReflectiveAspectJAdvisorFactory.getAdvice{
new AspectJMethodBeforeAdvice
new AspectJAfterAdvice
new AspectJAfterReturningAdvice
new AspectJAfterThrowingAdvice
new AspectJAroundAdvice
}
获取匹配的切面
- 代理目标类 targetSource
spring中并不是直接代理目标对象的,直接代理目标对象是无法拓展的,必须要有一个中间对象提供一些一致的操作,同时也可以封装一些特定场景的拓展,这中在spring中是非常常见的,如spring在创建bean的时候并不是直接就创建目标的bean,而是通过一个中间的对象BeanWrapper来提供统一的操作目标bean的方法。
-
相关类图
-
参考资料:
spring-aop组件详解——TargetSource目标源
- 遍历所有的切面,找到匹配的切面
AbstractAdvisorAutoProxyCreator.findEligibleAdvisors{}->
AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply{}->
AopUtils.findAdvisorsThatCanApply{}
AopUtils.canApply(Advisor advisor, Class<?> targetClass){}->
AopUtils.canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions){}->
AopUtils.canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions){}->
Pointcut.getMethodMatcher().matches{}
创建代理类
-
相关类图
-
流程解析
在创建ProxyFactory工厂的时候会将相关配置都设置进来,该对象中封装了两种具体逻辑(JdkDynamicAopProxy、ObjenesisCglibAopProxy),真正获取代理类是从这两个类里面获取出来的,ProxyFactory实现了proxyConfig接口,所以本身就是一个配置类,在创建具体这两个类的时候会将该本身传递过去。
AbstractAutoProxyCreator.postProcessBeforeInstantiation{}->
AbstractAutoProxyCreator.createProxy{}->
ProxyFactory.proxyFactory{}->//相关的配置信息会设置进去
DefaultAopProxyFactory.createAopProxy{}.getProxy{}->//JdkDynamicAopProxy、ObjenesisCglibAopProxy
JdkDynamicAopProxy 目标方法执行解析
-
相关类图
-
解析流程1:将Advisor适配成MethodInterceptor
在proxyFactory中创建了一个DefaultAdvisorChainFactory ,该对象可以讲所有的advisor对象适配成MethodInterceptor对象。
MethodInterceptor对象可以认为是一个拦截器,这里会将所有的拦截器组成一个拦截器链
JdkDynamicAopProxy.invoke{}->
ProxyFactory.getInterceptorsAndDynamicInterceptionAdvice{}->
DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice{}->
DefaultAdvisorAdapterRegistry.getInterceptors{}->//搞不懂一个切面为什么会被转换成多个MethodInterceptor
AdvisorAdapter.getInterceptor{}->// AfterReturningAdviceAdapter 、 MethodBeforeAdviceAdapter 、ThrowsAdviceAdapte
- 解析流程2:拦截器链的使用
接着上个流程,将拦截器链传入ReflectiveMethodInvocation,执行具体方法的时候会执行ReflectiveMethodInvocation.proceed方法,该方法中会调用MethodInterceptor.invoke,同时将ReflectiveMethodInvocation对象传递过去,在具体的MethodInterceptor.invoke中一般会回调ReflectiveMethodInvocation.proceed,这样就生成了一个由ReflectiveMethodInvocation对象连接的链。在ReflectiveMethodInvocation中定义了一个interceptorsAndDynamicMethodMatchers属性,记录当前所有需要执行的拦截器, currentInterceptorIndex记录当前执行到的拦截器,每次回调都会加1,直到执行完毕。
JdkDynamicAopProxy.invoke{}->
ReflectiveMethodInvocation.proceed{}
MethodInterceptor.invoke(ReflectiveMethodInvocatione){}
- 相关参考