使用“自動代理”功能
到目前為止,我們已經討論了使用 ProxyFactoryBean
或類似的工廠 bean 顯式建立 AOP 代理。
Spring 還允許我們使用“自動代理”bean 定義,這些定義可以自動代理選定的 bean 定義。這建立在 Spring 的“bean 後處理器”基礎設施之上,它允許在容器載入時修改任何 bean 定義。
在這種模型中,您可以在 XML bean 定義檔案中設定一些特殊的 bean 定義來配置自動代理基礎設施。這允許您宣告符合自動代理條件的目標。您無需使用 ProxyFactoryBean
。
有兩種方法可以實現
-
使用指向當前上下文中的特定 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 定義。BeanNameAutoProxyCreator
會自動建立 AOP 代理。相同的通知會應用於所有匹配的 bean。請注意,如果使用 advisor(而不是前一個示例中的攔截器),切入點可能會應用於不同的 bean。
DefaultAdvisorAutoProxyCreator
一個更通用且功能強大的自動代理建立器是 DefaultAdvisorAutoProxyCreator
。它會自動將當前上下文中的符合條件的 advisor 應用,而無需在自動代理 advisor 的 bean 定義中包含特定的 bean 名稱。它與 BeanNameAutoProxyCreator
一樣,提供了配置一致性和避免重複的優點。
使用此機制涉及
-
指定一個
DefaultAdvisorAutoProxyCreator
bean 定義。 -
在相同或相關的上下文中指定任意數量的 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,這允許在同一個工廠中使用多個配置不同的 AdvisorAutoProxyCreator)和排序。Advisor 可以實現 org.springframework.core.Ordered
介面以確保正確的排序(如果這是一個問題)。前一個示例中使用的 TransactionAttributeSourceAdvisor
具有可配置的順序值。預設設定是無序的。