手動配置 ProxyFactoryBean 雖然靈活,但隨著切面增多,XML 膨脹嚴重,且應用代碼需顯式從工廠獲取代理,耦合度高。Spring 提供兩大自動代理創建器,掃描容器中符合條件的 Bean 自動生成代理,實現「零侵入」AOP。
屬性:
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 直接運行,驗證通配符匹配生效。
無需指定 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 名稱。
| 特性 | BeanNameAutoProxyCreator | DefaultAdvisorAutoProxyCreator |
|---|---|---|
| 匹配方式 | Bean 名稱通配符 | Advisor 切點表達式 |
| 靈活度 | 低,僅限名稱 | 高,支援方法、類、註解等豐富切點 |
| 適用場景 | 簡單、固定命名規範的項目 | 企業級應用,需精細控制切面織入範圍 |
| 遷移成本 | 低 | 中 (需學習 Pointcut/Advisor) |
現代 Spring 應用建議直接使用
@EnableAspectJAutoProxy啟用 AspectJ 註解驅動 (@Aspect,@Pointcut,@Before等),功能更強大且代碼可讀性更高。本文兩類創建器屬 Spring 1.x/2.x 經典方案,理解其原理有助於掌握 AOP 底層機制。