public class TestBeforeAdvice implements MethodBeforeAdvice {
public void before(Method m, Object[] args, Object target) throws Throwable {
System.out.println("Hello world! (by " + this.getClass().getName() + ")");
}
}
三參數:目標方法、方法參數數組、目標對象引用。
public interface Bean { void theMethod(); }
public class BeanImpl implements Bean {
public void theMethod() {
System.out.println(this.getClass().getName() + ".theMethod() says HELLO!");
}
}
<beans>
<!-- 目標 Bean -->
<bean id="beanTarget" class="com.company.springaop.test.BeanImpl"/>
<!-- Advice -->
<bean id="theBeforeAdvice" class="com.company.springaop.test.TestBeforeAdvice"/>
<!-- Advisor: 正則切點 + Advice -->
<bean id="theAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice"><ref local="theBeforeAdvice"/></property>
<property name="pattern"><value>com\.company\.springaop\.test\.Bean\.theMethod</value></property>
</bean>
<!-- ProxyFactoryBean 創建代理 -->
<bean id="bean" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces"><value>com.company.springaop.test.Bean</value></property>
<property name="target"><ref local="beanTarget"/></property>
<property name="interceptorNames">
<list><value>theAdvisor</value></list>
</property>
</bean>
</beans>
ApplicationContext ctx = new FileSystemXmlApplicationContext("springconfig.xml");
Bean bean = (Bean) ctx.getBean("bean");
bean.theMethod();
輸出:
Hello world! (by com.company.springaop.test.TestBeforeAdvice)
com.company.springaop.test.BeanImpl.theMethod() says HELLO!
ProxyFactoryBean 生成實現 Bean 介面的 JDK 動態代理。interceptorNames 順序調用 Advisor。RegexpMethodPointcutAdvisor 用正則匹配方法簽名,性能好、可讀性強。| 優點 | 缺點 |
|---|---|
| 非侵入式、無需預編譯/字節碼增強 | 文檔相對較少(郵件列表補充) |
| 輕量級,可獨立於 J2EE 任何層使用 | 僅支援方法級攔截,無字段/構造子攔截 |
| 團隊僅需少數人懂 AOP,其餘正常開發 | 複雜切點表達需學習正則/AspectJ 語法 |
| 整合 Spring 生態(事務、DAO、Web MVC) |
Spring IDE (Eclipse 插件) 圖形化配置切點、通知、顧問,所見即所得。