使用“自動代理”功能
到目前為止,我們已經考慮了使用 ProxyFactoryBean 或類似的工廠 bean 顯式建立 AOP 代理。
Spring 還允許我們使用“自動代理”bean 定義,它可以自動代理選定的 bean 定義。這是建立在 Spring 的“bean 後處理器”基礎設施之上的,該基礎設施允許在容器載入時修改任何 bean 定義。
在這種模型中,您在 XML bean 定義檔案中設定了一些特殊的 bean 定義,以配置自動代理基礎設施。這允許您宣告符合自動代理條件的 target。您不需要使用 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)的正確行為。命名的“攔截器”可以是通知器或任何通知型別。
與一般自動代理一樣,使用 BeanNameAutoProxyCreator 的主要目的是以最少的配置量,將相同的配置一致地應用於多個物件。它是將宣告式事務應用於多個物件的流行選擇。
名稱匹配的 bean 定義,例如前面示例中的 jdkMyBean 和 onlyJdk,是帶有目標類的普通舊 bean 定義。AOP 代理由 BeanNameAutoProxyCreator 自動建立。相同的通知應用於所有匹配的 bean。請注意,如果使用通知器(而不是前面示例中的攔截器),則切入點可能對不同的 bean 應用方式不同。
DefaultAdvisorAutoProxyCreator
一個更通用且功能強大的自動代理建立器是 DefaultAdvisorAutoProxyCreator。它自動應用當前上下文中符合條件的通知器,而無需在自動代理通知器的 bean 定義中包含特定的 bean 名稱。它提供了與 BeanNameAutoProxyCreator 相同的優點:一致的配置和避免重複。
使用此機制包括
-
指定
DefaultAdvisorAutoProxyCreatorbean 定義。 -
在相同或相關上下文中指定任意數量的通知器。請注意,這些必須是通知器,而不是攔截器或其他通知。這是必要的,因為必須有一個要評估的切入點,以檢查每個通知對候選 bean 定義的適用性。
DefaultAdvisorAutoProxyCreator 自動評估每個通知器中包含的切入點,以檢視它應該對每個業務物件(例如示例中的 businessObject1 和 businessObject2)應用什麼(如果有的話)通知。
這意味著任意數量的通知器可以自動應用於每個業務物件。如果任何通知器中的任何切入點與業務物件中的任何方法不匹配,則該物件不會被代理。隨著為新的業務物件新增 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 支援過濾(透過使用命名約定,以便只評估某些通知器,這允許在同一工廠中使用多個不同配置的 AdvisorAutoProxyCreator)和排序。如果這是一個問題,通知器可以實現 org.springframework.core.Ordered 介面以確保正確的排序。前面示例中使用的 TransactionAttributeSourceAdvisor 具有可配置的排序值。預設設定為無序。