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