[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{}
查找全部非@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排序切面
AbstractAdvisorAutoProxyCreator.findEligibleAdvisors{}-> AspectJAwareAdvisorAutoProxyCreator.sortAdvisors{}-> new PartiallyComparableAdvisorHolde(new AspectJPrecedenceComparator()){}->
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 }
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
相关类图
解析流程1:将Advisor适配成MethodInterceptor
在proxyFactory中建立了一个DefaultAdvisorChainFactory ,该对象能够讲全部的advisor对象适配成MethodInterceptor对象。
MethodInterceptor对象能够认为是一个拦截器,这里会将全部的拦截器组成一个拦截器链
JdkDynamicAopProxy.invoke{}-> ProxyFactory.getInterceptorsAndDynamicInterceptionAdvice{}-> DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice{}-> DefaultAdvisorAdapterRegistry.getInterceptors{}->//搞不懂一个切面为何会被转换成多个MethodInterceptor AdvisorAdapter.getInterceptor{}->// AfterReturningAdviceAdapter 、 MethodBeforeAdviceAdapter 、ThrowsAdviceAdapte
接着上个流程,将拦截器链传入ReflectiveMethodInvocation,执行具体方法的时候会执行ReflectiveMethodInvocation.proceed方法,该方法中会调用MethodInterceptor.invoke,同时将ReflectiveMethodInvocation对象传递过去,在具体的MethodInterceptor.invoke中通常会回调ReflectiveMethodInvocation.proceed,这样就生成了一个由ReflectiveMethodInvocation对象链接的链。在ReflectiveMethodInvocation中定义了一个interceptorsAndDynamicMethodMatchers属性,记录当前全部须要执行的拦截器, currentInterceptorIndex记录当前执行到的拦截器,每次回调都会加1,直到执行完毕。
JdkDynamicAopProxy.invoke{}-> ReflectiveMethodInvocation.proceed{} MethodInterceptor.invoke(ReflectiveMethodInvocatione){}