帶你了解如何使用Spring基于ProxyFactoryBean創(chuàng)建AOP代理
若使用 Spring IoC 容器(ApplicationContext或BeanFactory)作為你的業(yè)務(wù)對(duì)象(你也應(yīng)該這么做?。?,你會(huì)想使用 Spring AOP FactoryBean的一種。
工廠 bean 引入了中間層,讓它創(chuàng)建不同類型的對(duì)象。
在Spring創(chuàng)建 AOP 代理的基本方式是使用 org.springframework.aop.framework.ProxyFactoryBean。這可以完全控制pointcuts、使用的任何通知和他們的順序。但若不需要這樣的控制,也有更簡(jiǎn)單的選擇。
1 基礎(chǔ)
ProxyFactoryBean,類似其他 Spring 的FactoryBean實(shí)現(xiàn),引入了中間層。
若你定義了名為 foo 的ProxyFactoryBean,則引用 foo 的對(duì)象不會(huì)看到ProxyFactoryBean實(shí)例本身,而是在ProxyFactoryBean中實(shí)現(xiàn)的 getObject()創(chuàng)建的對(duì)象。該方法創(chuàng)建了一個(gè)包裝目標(biāo)對(duì)象的 AOP 代理。
使用ProxyFactoryBean或其他 IoC-aware 類創(chuàng)建 AOP 代理的最大好處之一是advices和pointcuts也可以由 IoC 管理。這是一個(gè)強(qiáng)大的功能,使某些方法很難用AOP 實(shí)現(xiàn)的開(kāi)啟了新途徑。例如,advice本身可能引用應(yīng)用對(duì)象(不僅是目標(biāo)對(duì)象,該對(duì)象應(yīng)在任何 AOP 框架中都可用),從而受益于DI提供的所有可插拔性。
2 JavaBean屬性
與大多數(shù)FactoryBean實(shí)現(xiàn)類似, ProxyFactoryBean類本身就是一個(gè)JavaBean。
其屬性用于:
- 指定要代理的目標(biāo)
- 指定是否使用 CGLIB
一些關(guān)鍵屬性是從 org.springframework.aop.framework.ProxyConfig (Spring所有 Aop 代理工廠的父類) 繼承的。這些關(guān)鍵屬性包括:
- proxyTargetClass
如果要代理目標(biāo)類,而不是目標(biāo)類的接口,則為 true。如果此屬性值設(shè)置為true,則創(chuàng)建 CGLIB 代理
- optimize
控制是否將主動(dòng)優(yōu)化應(yīng)用于通過(guò) CGLIB 創(chuàng)建的代理。除非你完全了解相關(guān)的 AOP 代理如何處理優(yōu)化,否則您不應(yīng)輕率地使用此設(shè)置。僅用于 CGLIB 代理,對(duì) JDK 動(dòng)態(tài)代理無(wú)影響。
- frozen
如果代理配置被凍結(jié),則不再允許更改配置。這既是一種輕微的優(yōu)化,也是在不希望調(diào)用者在創(chuàng)建代理后(通過(guò)建議的接口)操縱代理時(shí),這些情況是有用的。默認(rèn)值false,即允許更改(比如添加額外advice)。
- exposeProxy
確定當(dāng)前代理是否應(yīng)在ThreadLocal暴露,以便目標(biāo)可以訪問(wèn)該代理。如果目標(biāo)需要獲取代理并將暴露的 Proxy 屬性設(shè)置為true,則目標(biāo)可以使用 AopContext.當(dāng)前普羅西 () 方法。
ProxyFactoryBean其他屬性包括:
- proxyInterfaces
字符串接口名稱的數(shù)組。若不提供此,則使用目標(biāo)類的 CGLIB 代理
- interceptorNames
要應(yīng)用的Advisor、攔截器或其他建議名稱的字符串?dāng)?shù)組。順序非常重要,首先先到先得。也就是說(shuō),列表中的第一個(gè)攔截器是能夠攔截調(diào)用的第一個(gè)攔截器。
這些名稱是當(dāng)前工廠中的bean名稱,包括來(lái)自祖先工廠的bean名稱。你不能在這里使用bean引用, 因?yàn)檫@樣做會(huì)導(dǎo)致
ProxyFactoryBean忽略了推薦的單例設(shè)置。
可以用 * 附加攔截器名稱。這樣做會(huì)導(dǎo)致應(yīng)用所有advisor beans與名稱,開(kāi)始與*應(yīng)用前的部分。
- singleton
工廠是否應(yīng)該返回單例的對(duì)象,無(wú)論getObject()調(diào)用頻率如何,幾個(gè)FactoryBean實(shí)現(xiàn)都提供這樣的方法。默認(rèn)值為true。如果你想使用有狀態(tài)的advice,使用prototype 類型的advices以及false的singleton值。
3 JDK和CGLIB代理
ProxyFactoryBean如何選擇為特定目標(biāo)對(duì)象(將代理)創(chuàng)建基于 JDK 的代理或基于 CGLIB 的代理。
ProxyFactoryBean在創(chuàng)建基于 JDK 或 CGLIB 的代理方面的行為在Spring的 1.2.x 版本和 2.0
版本之間發(fā)生了變化。ProxyFactoryBean現(xiàn)在在自動(dòng)檢測(cè)接口方面表現(xiàn)出與TransactionProxyFactoryBean類類似的語(yǔ)義。
如果要代理的目標(biāo)對(duì)象類別(以下簡(jiǎn)稱目標(biāo)類)不實(shí)現(xiàn)任何接口,則創(chuàng)建基于 CGLIB 的代理。這是最簡(jiǎn)單的方案,因?yàn)?JDK 代理是基于接口的,沒(méi)有接口意味著 JDK 代理甚至是不可能的。您可以插入目標(biāo)豆,并通過(guò)設(shè)置攔截器命名屬性來(lái)指定攔截器列表。請(qǐng)注意,即使代理工廠豆的代理目標(biāo)類屬性被設(shè)置為虛假,也創(chuàng)建基于 CGLIB 的代理。(這樣做是沒(méi)有意義的,最好從豆的定義中刪除,因?yàn)樗淦淞渴嵌嘤嗟?,而且,在最壞的情況下是令人困惑的。
總結(jié)
本篇文章就到這里了,希望能給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
詳解springboot+mybatis-plue實(shí)現(xiàn)內(nèi)置的CRUD使用詳情
這篇文章主要介紹了詳解springboot+mybatis-plue實(shí)現(xiàn)內(nèi)置的CRUD使用詳情,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
Spring Cloud超詳細(xì)i講解Feign自定義配置與使用
這篇文章主要介紹了SpringCloud Feign自定義配置與使用,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06
Spring Data JPA開(kāi)啟批量更新時(shí)樂(lè)觀鎖失效問(wèn)題的解決方法
樂(lè)觀鎖的基本思想是,認(rèn)為在大多數(shù)情況下,數(shù)據(jù)訪問(wèn)不會(huì)導(dǎo)致沖突,因此,樂(lè)觀鎖允許多個(gè)事務(wù)同時(shí)讀取和修改相同的數(shù)據(jù),而不進(jìn)行顯式的鎖定,本文給大家介紹了Spring Data JPA開(kāi)啟批量更新時(shí)樂(lè)觀鎖失效問(wèn)題的解決方法,需要的朋友可以參考下2024-07-07
Java并發(fā)編程示例(六):等待線程執(zhí)行終止
這篇文章主要介紹了Java并發(fā)編程示例(六):等待線程執(zhí)行終止,在本節(jié),示例程序演示等待初始化方法完成后,再去執(zhí)行其他任務(wù),需要的朋友可以參考下2014-12-12
解決mapper.xml中resultType映射類型的問(wèn)題
這篇文章主要介紹了解決mapper.xml中resultType映射類型的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06

