您好,登錄后才能下訂單哦!
這篇文章主要介紹“Spring中AOP模塊的概述和創建方法”,在日常操作中,相信很多人在Spring中AOP模塊的概述和創建方法問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Spring中AOP模塊的概述和創建方法”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
概述
spirng-aop模塊是Spring框架中的核心模塊,雖然Spring Ioc container并不依賴AOP,但AOP給Ioc的實現提供了一種強大而靈活的解決方案。
在Spring Framework中,AOP主要是用于兩種目的:
提供一些 企業 級的聲明式服務,典型的應用如 declarative transaction management .
允許用戶實現自己的aspects,用AOP的方式來幫助和補充OOP的功能及實現
AOP從功能的角度來講,可能看作OOP編程方式的一種補充,提供了一種不同的代碼或者系統組織方式。OOP中的核心概念是Class,而在AOP中則是Aspect。
spirng-aop模塊是Spring框架中的核心模塊,雖然Spring Ioc container并不依賴AOP,但AOP給Ioc的實現提供了一種強大而靈活的解決方案。
在Spring Framework中,AOP主要是用于兩種目的:
提供一些企業級的聲明式服務,典型的應用如 declarative transaction management.
允許用戶實現自己的aspects,用AOP的方式來幫助和補充OOP的功能及實現
Spring AOP由純Java實現,無須特殊的編譯處理,也不需要控制類加載器的層次結構,所以它可以適用于Servlet Container和其它application server.
Spring AOP目前只支持方法級別的切換或攔截,屬性的攔截現在不支持,如果想要攔截屬性,可以考慮使用AspectJ語言。
Spring AOP的使用不同于其它大多數AOP框架。它的主要目的不是提供一套大而全的AOP實現,而是集成AOP不同實現協同Spring Ioc來幫助解決一些普遍性問題。
需要注意的是,一些細粒度的advised(如domain model),Spring AOP往往不能提供很好的支持,這場景也還是考慮AspectJ。即使如此,就普遍經驗來說Spring AOP的強大機制依然能夠解決大多數場景的問題。
那么該如何看待Spring AOP和AspectJ,引用Spring官方文檔的原文:
Spring AOP will never strive to compete with AspectJ to provide a comprehensive AOP solution. We believe that both proxy-based frameworks like Spring AOP and full-blown frameworks such as AspectJ are valuable, and that they are complementary, rather than in competition. Spring seamlessly integrates Spring AOP and IoC with AspectJ, to enable all uses of AOP to be catered for within a consistent Spring-based application architecture. This integration does not affect the Spring AOP API or the AOP Alliance API: Spring AOP remains backward-compatible.
在Spring框架所有的模塊設計中,始終遵守的核心信條之一是——無侵入性。
所以在使用Spring AOP時,不會強制我們在業務代碼中引入特定類或者接口,可以最大限度的保持代碼 clean and decouple。然而Spring也提供了另一種選擇,如果有特定的場景需要的話,你可以在你的代碼中直接引入Spring AOP。幾乎所有Spring框架中的模塊,在使用的方式上都會給你多種選擇,以便讓用戶選擇更適合自己場景的方式。使用AspectJ還是Spring AOP,使用annotation方式還是xml的配置方式,Depends On U。
了解了Spring AOP的初衷和使用場景,來看下它的大致實現原理
在軟件世界中的絕大多數問題,都可以通過加一層來解決。
這里所說的層,當然是廣義上的,可以是一層抽象,也可以是一層cache,大致含義是隔離和解耦的范疇。
在Spring的世界里,每一個模塊的引入,或者第三方技術的集成,總會提供一個抽象層 ,對用戶提供統一的API,屏蔽了所有的實現細節以及不同實現的差異。例如spring-cache,spring-jdbc,spring-jms以及spirng-messaging等模塊都提供了一層抽象。
Spring AOP的實現是基于代理的機制,默認是采用Jdk dynamic proxy,也可以采用cglib的proxy。兩者的區別主要是在于被代理的對象的不同。當目標對象是接口時,Jdk dynamic proxy可以完成代理,但目標對象是沒有實現接口的類時(盡量少一些,面向接口編程是好習慣),是需要采用cglib proxy來完成代理的,當然你也可以強制接口也采用cglib來代理;另外需要注入或引用具體類型時,如果引用的東西恰恰是代理過的對象,此時也需要采用cglib的方式。
功能設計和實現上來可以分為兩大塊
aop基礎設施的創建,可以看作是aopProxy的生成
aopProxy對象的調用時的處理攔截,即處理對目標對象的攔截器
AOP的創建
生成代理對象的核心類,ProxyFactoryBean getObjecct()
下圖是生成代理時,是用Jdk還是cglib的選擇邏輯:
找到了生成代理的具體執行者,那么這個操作是在什么時候被調用的呢,了解過Spring bean生命周期的都應該知道,bean在創建的時候,有一系列的回調接口供用戶插入自定義的行為,來左右bean的一些特性,其中BeanPostProcessor是接口中的一種。以往的文章有介紹過(玩轉Spring bean的終極利器)。而Spring AOP正是利用這個契機,在創建bean的過程中插了一手,如果正在創建的bean是我們aop的target,則創建代理,并最終把代理對象返回給Ioc。
AbstractAutoProxyCreator 這個類是一個BeanPostProcessor的實現,用來創建代理,來看這個處理器的后處理方法,最終是返回了createProxy()方法返回的代理
AOP切面的增強的執行
可以理解成對目標對象上所有攔截器鏈的調用
由于Spring AOP的代理具體實現有兩種,JDK dynamic proxy和cglib,所以執行攔截器的方式有所不同,具體可以閱讀源碼JdkDynamicAopProxy類的invoke方法
對目標方法的調用最終是依靠ReflectiveMethodInvocation.
ReflectiveMethodInvocation中的proceed處理是采用遞歸的方式處理攔截器鏈
CglibAopProxy的 intercept方法
CglibMethodInvoation是繼承了ReflectiveMethodInvocation,處理攔截器鏈也是用的上邊的proceed()方法。
在使用Spring AOP時需要注意的兩點細節:
1、在類內部的方法調用時(self-invoke),Spring AOP不起作用,原因是內部調用沒通過代理對象,直接使用的目標對象。解決方法有:
重構代碼,避免內部調用
AopContext.currentProxy()
或者干脆使用AspectJ語言吧...
2、在注入bean時,如果想注入bean的具體的類型而不是接口,那么采用cglib吧
到此,關于“Spring中AOP模塊的概述和創建方法”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。