Aspect动态aop

[toc]spring

##使用讲解缓存

  • 编写aspect类,并使用@component加入spring的容器app

  • aop:aspectj-autoproxy/ 会在spring建立bean的时候应用@Aspect注解的切点和通知post

##源码解析ui

想把全部的@aspect注解的bean 转换成advisor ,而后从中找到匹配当前bean的advosor,建立代理类this

入口

AspectJAwareAdvisorAutoProxyCreator是继承与SmartInstantiationAwareBeanPostProcessor接口的,该接口会在建立完bean以后执行postProcessBeforeInstantiation方法,spring容器中实际返回的对象是通过该方法处理后的对象,也就是代理对象,每一个bean可能会适配多个切面,spring的处理时将全部的切面转换成拦截器(MethodInteceptor),而后将拦截器生成一个链,按照指定的顺序执行。.net

  • 相关类图代理

  • 启动方法code

AbstractAutoProxyCreator.postProcessBeforeInstantiation{}

获取切面 InstantiationModelAwarePointcutAdvisorImpl

查找全部非@PointCut注解的方法,若是方法上面有{Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class}这些注解,则认为这个是一个advice,就会去建立一个切面,经过方法上面注解的切点表达式来建立切点,在建立完以后会统一的缓存下来的(BeanFactoryAspectJAdvisorsBuilder.advisorsCache)。component

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深刻理解之拦截器调用

相关文章
相关标签/搜索