首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Spring 自動代理機制詳解:BeanNameAutoProxyCreator 與 DefaultAdvisorAutoProxyCreator

     編輯:Java 相關知識

手動配置 ProxyFactoryBean 雖然靈活,但隨著切面增多,XML 膨脹嚴重,且應用代碼需顯式從工廠獲取代理,耦合度高。Spring 提供兩大自動代理創建器,掃描容器中符合條件的 Bean 自動生成代理,實現「零侵入」AOP。

方案一:BeanNameAutoProxyCreator — 按 Bean 名稱匹配

屬性:

  • beanNames:String[],支援通配符 (如 *DAO、Service*)。
  • interceptorNames:String[],通知或切點通知器列表。

實戰範例

<beans>
    <bean id="TestBeanA" class="aop.test.TestBeanA"/>
    <bean id="BeanB" class="aop.test.BeanB"/>
    <bean id="BeforeAdvice" class="aop.test.BeforeAdvice"/>

    <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
        <property name="beanNames">
            <list><value>Test*</value></list> <!-- 僅代理 Test 開頭的 Bean -->
        </property>
        <property name="interceptorNames">
            <list><value>BeforeAdvice</value></list>
        </property>
    </bean>
</beans>

測試類:

public class TestMain {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        TestBeanA beanA = (TestBeanA) ac.getBean("TestBeanA"); // 直接獲取目標 Bean
        beanA.MyMethod(); // 前置通知自動觸發
        BeanB beanB = (BeanB) ac.getBean("BeanB"); // 不會被代理
        beanB.MyMethod();
    }
}

輸出:

MyMethod(),將要運行!
aop.test.TestBeanA.MyMethod() is run!
aop.test.BeanB.MyMethod() is run!

只有 TestBeanA 被代理,BeanB 直接運行,驗證通配符匹配生效。

方案二:DefaultAdvisorAutoProxyCreator — 基於 Advisor 自動代理

無需指定 beanNames,容器中所有 Advisor 類型的 Bean 會被自動識別並應用到所有匹配切點的 Bean 上。

配置範例

<beans>
    <bean id="TestBeanA" class="aop.test.TestBeanA"/>
    <bean id="BeanB" class="aop.test.BeanB"/>
    <bean id="BeforeAdvice" class="aop.test.BeforeAdvice"/>

    <!-- 自動代理創建器 -->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>

    <!-- 定義 Advisor:切點 + 通知 -->
    <bean class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
        <property name="advice" ref="BeforeAdvice"/>
        <property name="mappedNames">
            <list><value>*Method*</value></list> <!-- 匹配方法名含 Method -->
        </property>
    </bean>
</beans>

效果相同,但更符合「切面定義與目標對象解耦」的 AOP 精髓:只需編寫 Advisor,無關目標 Bean 名稱。

兩者對比與選型建議

特性BeanNameAutoProxyCreatorDefaultAdvisorAutoProxyCreator
匹配方式Bean 名稱通配符Advisor 切點表達式
靈活度低,僅限名稱高,支援方法、類、註解等豐富切點
適用場景簡單、固定命名規範的項目企業級應用,需精細控制切面織入範圍
遷移成本低中 (需學習 Pointcut/Advisor)

現代 Spring 應用建議直接使用 @EnableAspectJAutoProxy 啟用 AspectJ 註解驅動 (@Aspect, @Pointcut, @Before 等),功能更強大且代碼可讀性更高。本文兩類創建器屬 Spring 1.x/2.x 經典方案,理解其原理有助於掌握 AOP 底層機制。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved