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