使用 "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 定義,例如前面範例中的 jdkMyBeanonlyJdk,是具有目標類別的普通 Bean 定義。AOP 代理由 BeanNameAutoProxyCreator 自動建立。相同的通知會應用於所有相符的 Bean。請注意,如果使用 Advisor(而不是前面範例中的攔截器),則切入點可能會以不同的方式應用於不同的 Bean。

DefaultAdvisorAutoProxyCreator

更通用且功能極其強大的自動代理建立器是 DefaultAdvisorAutoProxyCreator。這會自動將目前 Context 中符合條件的 Advisor 應用於 Bean,而無需在自動代理 Advisor 的 Bean 定義中包含特定的 Bean 名稱。它提供了與 BeanNameAutoProxyCreator 相同的一致組態和避免重複的優點。

使用此機制涉及

  • 指定 DefaultAdvisorAutoProxyCreator Bean 定義。

  • 在相同或相關的 Context 中指定任意數量的 Advisor。請注意,這些必須是 Advisor,而不是攔截器或其他通知。這是必要的,因為必須有一個切入點來評估,以檢查每個通知對候選 Bean 定義的資格。

DefaultAdvisorAutoProxyCreator 會自動評估每個 Advisor 中包含的切入點,以查看它應該將什麼(如果有)通知應用於每個業務物件(例如範例中的 businessObject1businessObject2)。

這表示可以將任意數量的 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 具有可組態的順序值。預設設定為未排序。