使用 "auto-proxy" 功能
到目前為止,我們已經考慮使用 ProxyFactoryBean
或類似的 Factory Bean 明確建立 AOP 代理。
Spring 也允許我們使用「自動代理」Bean 定義,它可以自動代理選定的 Bean 定義。這是建立在 Spring 的「Bean 後處理器」基礎架構之上,該基礎架構能夠在容器載入時修改任何 Bean 定義。
在這個模型中,您需要在 XML Bean 定義檔案中設定一些特殊的 Bean 定義,以組態自動代理基礎架構。這讓您可以宣告符合自動代理條件的目標。您不需要使用 ProxyFactoryBean
。
有兩種方法可以做到這一點
-
透過使用參照目前 Context 中特定 Bean 的自動代理建立器。
-
一種特殊的自動代理建立情況,值得單獨考慮:由來源層級元資料屬性驅動的自動代理建立。
自動代理 Bean 定義
本節介紹 org.springframework.aop.framework.autoproxy
套件提供的自動代理建立器。
BeanNameAutoProxyCreator
BeanNameAutoProxyCreator
類別是一個 BeanPostProcessor
,它會自動為名稱與常值或萬用字元相符的 Bean 建立 AOP 代理。以下範例顯示如何建立 BeanNameAutoProxyCreator
Bean
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames" value="jdk*,onlyJdk"/>
<property name="interceptorNames">
<list>
<value>myInterceptor</value>
</list>
</property>
</bean>
與 ProxyFactoryBean
相同,有一個 interceptorNames
屬性,而不是攔截器列表,以便允許原型 Advisor 的正確行為。具名的「攔截器」可以是 Advisor 或任何通知類型。
與一般的自動代理一樣,使用 BeanNameAutoProxyCreator
的主要目的是將相同的組態一致地應用於多個物件,並盡可能減少組態量。它是將宣告式交易應用於多個物件的熱門選擇。
名稱相符的 Bean 定義,例如前面範例中的 jdkMyBean
和 onlyJdk
,是具有目標類別的普通 Bean 定義。AOP 代理由 BeanNameAutoProxyCreator
自動建立。相同的通知會應用於所有相符的 Bean。請注意,如果使用 Advisor(而不是前面範例中的攔截器),則切入點可能會以不同的方式應用於不同的 Bean。
DefaultAdvisorAutoProxyCreator
更通用且功能極其強大的自動代理建立器是 DefaultAdvisorAutoProxyCreator
。這會自動將目前 Context 中符合條件的 Advisor 應用於 Bean,而無需在自動代理 Advisor 的 Bean 定義中包含特定的 Bean 名稱。它提供了與 BeanNameAutoProxyCreator
相同的一致組態和避免重複的優點。
使用此機制涉及
-
指定
DefaultAdvisorAutoProxyCreator
Bean 定義。 -
在相同或相關的 Context 中指定任意數量的 Advisor。請注意,這些必須是 Advisor,而不是攔截器或其他通知。這是必要的,因為必須有一個切入點來評估,以檢查每個通知對候選 Bean 定義的資格。
DefaultAdvisorAutoProxyCreator
會自動評估每個 Advisor 中包含的切入點,以查看它應該將什麼(如果有)通知應用於每個業務物件(例如範例中的 businessObject1
和 businessObject2
)。
這表示可以將任意數量的 Advisor 自動應用於每個業務物件。如果任何 Advisor 中的切入點與任何業務物件中的任何方法都不符,則不會代理該物件。當為新的業務物件新增 Bean 定義時,如果需要,它們會自動被代理。
一般而言,自動代理的優點是,呼叫者或依賴項不可能取得未經通知的物件。在此 ApplicationContext
上呼叫 getBean("businessObject1")
會傳回 AOP 代理,而不是目標業務物件。(前面顯示的「內部 Bean」慣用語也提供了此優點。)
以下範例建立 DefaultAdvisorAutoProxyCreator
Bean 和本節中討論的其他元素
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
<bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
<property name="transactionInterceptor" ref="transactionInterceptor"/>
</bean>
<bean id="customAdvisor" class="com.mycompany.MyAdvisor"/>
<bean id="businessObject1" class="com.mycompany.BusinessObject1">
<!-- Properties omitted -->
</bean>
<bean id="businessObject2" class="com.mycompany.BusinessObject2"/>
如果您想要將相同的通知一致地應用於許多業務物件,則 DefaultAdvisorAutoProxyCreator
非常有用。一旦基礎架構定義到位,您就可以新增新的業務物件,而無需包含特定的代理組態。您也可以輕鬆地添加額外的切面(例如,追蹤或效能監控切面),而只需對組態進行最少的變更。
DefaultAdvisorAutoProxyCreator
支援篩選(透過使用命名慣例,以便僅評估某些 Advisor,這允許在同一個 Factory 中使用多個、組態不同的 AdvisorAutoProxyCreator)和排序。Advisor 可以實作 org.springframework.core.Ordered
介面,以確保在出現問題時的正確排序。前面範例中使用的 TransactionAttributeSourceAdvisor
具有可組態的順序值。預設設定為未排序。