Aspect动态aop

[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){}

  • 相关参考

Spring AOP深入理解之拦截器调用

转载于:https://my.oschina.net/u/2298333/blog/718896

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值