Spring AOP底層源碼詳解
ProxyFactory的工作原理
ProxyFactory是一個代理對象生產工廠,在生成代理對象之前需要對代理工廠進行配置。ProxyFactory在生成代理對象之前需要決定到底是使用JDK動態代理還是CGLIB技術。
// config就是ProxyFactory對象 // optimize為true,或proxyTargetClass為true,或用戶沒有給ProxyFactory對象添加interface if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } // targetClass是接口,直接使用Jdk動態代理 if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } // 使用Cglib return new ObjenesisCglibAopProxy(config); } else { // 使用Jdk動態代理 return new JdkDynamicAopProxy(config); }
JdkDynamicAopProxy創建代理對象過程
- 獲取生成代理對象所需要實現的接口集合
- 獲取通過ProxyFactory.addInterface()所添加的接口,如果沒有通過ProxyFactory.addInterface()添加接口,那麼則看ProxyFactory。setTargetClass()所設置的targetClass是不是一個接口,把接口添加到結果集合中,同時把SpringProxy、Advised、DecoratingProxy這幾個接口也添加到結果集合中去。
- 確定好要代理的集合之後,就利用Proxy.newProxyInstance()生成一個代理對象。
JdkDynamicAopProxy創建代理對象執行過程
- 如果通過ProxyFactory.setExposeProxy()把exposeProxy設置為true,那麼則把代理對象設置到一個ThreadLocal(currentProxy)中去。
- 獲取通過ProxyFactory所設置的target,如果設置的是targetClass,那麼target將為null
- 根據當前所調用的方法對象尋找ProxyFactory中所添加的並匹配的Advisor,並且把Advisor封裝為MethodInterceptor返回,得到MethodIntercepter鏈叫做chain
- 如果chain為空,則字節執行target對應的當前方法,如果target為null會報錯
- 如果chain不為空,則會依次執行chain中的MethodInterceptor。如果當前MethodInterceptor是MethodBeforeAdviceInterceptor,那麼先執行Advisor中所advice的before()方法,然後執行下一個MethodInterceptor.如果當前MethodInterceptor是AfterReturningAdviceInterceptor,那麼先執行執行下一個MethodInterceptor。拿到返回值後,再執行Advisor中所advice的afterReturning()方法
ObjenesisCglibAopProxy創建代理對象過程
- 創建Enhancer
- 設置Enhancer的superClass為通過ProxyFactory.setTarget()所設置的對象的類
- 設置Enhancer的interfaces為通過ProxyFactory.addInterface()所添加的接口,以及SpringProxy、Advisor接口
- 設置Enhancer的Callbacks為DynamicAdvisedIntercepter
- 最後通過Enhancer創建一個代理對象
ObjenesisCglibAopProxy創建的代理對象執行過程
執行過程主要就看DynamicAdvisedInterceptor中的實現,執行邏輯和JdkDynamicAopProxy中是一樣的。
自動代理(autoproxy)功能
“自動代理”表示隻需要在Spring中添加某個Bean,這個Bean是一個BeanPostProcessor,那麼Spring在每創建一個Bean時,都會經過這個BeanPost Processor的判斷,去判斷當前正在創建的這個Bean是不是需要進行AOP。
DefaultAdvisorAutoProxyCreator
AbstractAutoProxyCreator實現瞭SmartInstantiationAwareBeanPostProcessor接口,是一個BeanPostProcessor
- 在某個Bean實例化之前,查看該AbstractAutoProxyCreator中是不是設置瞭CustomTargetSource,如果設置瞭就查看當前Bean是不是需要創建一個TargetSource,如果需要就會創建一個TargetSource對象,然後進行AOP創建一個代理對象,並返回該代理對象
- 如果某個Bean出現瞭循環依賴,那麼會利用getEarlyBeanReference()方法提前進行AOP
- 在某個Bean初始化之後,會調用wrapIfNecessary()方法進行AOP
- 在這個類中提供瞭一個抽象方法:getAdvicesAndAdvisorsForBean(),表示對於某個Bean匹配瞭哪些Advices和Advisors
AbstractAdvisorAutoProxyCreator繼承瞭AbstractAutoProxyCreator,AbstractAdvisorAutoProxyCreator中實現瞭getAdvicesAndAdvisorsForBean()方法,實現邏輯為:
- 調用findEligibleAdvisors()
- 調用findCandidateAdvisors,得到所有Advisor類型的Bean。按當前正在進行Bean的生命周期的Bean進行過濾
@EnableAspectJAutoProxy
這個註解主要是添加瞭一個AnnotationAwareAspectJAutoProxyCreator類型的BeanDefinition。AspectJAwareAdvisorAutoProxyCreator繼承瞭AbstractAdvisorAutoProxyCreator,重寫瞭shouldSkip(Class<?> beanClass, String beanName)方法,表示某個bean需不需要進行AOP,在shouldSkip()方法中:
- 拿到所有的Advisor
- 遍歷所有的Advisor,如果當前bean是AspectJPointcutAdvisor,那麼則跳過
AnnotationAwareAspectJAutoProxyCreator繼承瞭AspectJAwareAdvisorAutoProxyCreator,重寫瞭findCandidateAdvisors()方法,它即可以找到Advisor類型的bean,也能把所有@Aspect註解標註的類掃描出來並生成Advisor
註解和源碼對應關系
@Before對應的是AspectJMethodBeforeAdvice,直接實現MethodBeforeAdvice,在進行動態代理時會把AspectJMethodBeforeAdvice轉成MethodBeforeAdviceInterceptor,也就轉變成瞭MethodBeforeAdviceInterceptor
- 先執行advice對應的方法
- 再執行MethodInvocation的proceed(),會執行下一個Interceptor,如果沒有下一個Interceptor瞭,會執行target對應的方法
@After對應的是AspectJAfterAdvice,直接實現瞭MethodInterceptor
- 先執行MethodInvocation的proceed(),會執行下一個Interceptor,如果沒有下一個Interceptor瞭,會執行target對應的方法
- 再執行advice對應的方法
@Around對應的是AspectJAroundAdvice,直接實現瞭MethodInterceptor
直接執行advice對應的方法
@AfterThrowing對應的是AspectJAfterThrowingAdvice,直接實現瞭MethodInterceptor
- 先執行MethodInvocation的proceed(),會執行下一個Interceptor,如果沒有下一個Interceptor瞭,會執行target對應的方法
- 如果上面拋瞭Throwable,那麼則會執行advice對應的方法
@AfterReturning對應的是AspectJAfterReturningAdvice,實現瞭AfterReturningAdvice,在進行動態代理時會把AspectJAfterReturningAdvice轉成AfterReturningAdviceInterceptor,也就轉變成瞭MethodInterceptor
- 先執行MethodInvocation的proceed(),會執行下一個Interceptor,如果沒有下一個Interceptor瞭,會執行target對應的方法
- 執行上面的方法後得到最終的方法的返回值
- 再執行Advice對應的方法
以上就是Spring AOP底層源碼詳解的詳細內容,更多關於Spring AOP底層源碼的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- 使用Spring方法攔截器MethodInterceptor
- Spring開發核心之AOP的實現與切入點持久化
- Spring源碼學習之動態代理實現流程
- Spring深入刨析聲明式事務註解的源碼
- SpringBoot中利用AOP和攔截器實現自定義註解