專案若使用 JDK 1.4 或不想用註解,可改用 Spring XML Schema-based AOP 命名空間,功能與 @AspectJ 等價,配置移至 XML。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="https://www.springframework.org/schema/aop"
xsi:schemaLocation="
https://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans-2.5.xsd
https://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
...
</beans>
<aop:config>所有 AOP 配置皆為其子標籤。本範例攔截 People.sayHello() 並在執行前輸出日誌。
Peoplepublic class People {
public String sayHello(String str) {
System.out.println(this.getClass().getName() + "說:" + str);
return str;
}
}
MyAspectpublic class MyAspect {
public void beforeAdvice(JoinPoint point) {
System.out.println("前置通知被觸發:" +
point.getTarget().getClass().getName() + "將要" + point.getSignature().getName());
}
}
<bean id="MyAspect" class="aop.test.MyAspect"/>
<bean id="TestBean" class="aop.test.People"/>
<aop:config proxy-target-class="true">
<aop:aspect ref="MyAspect" order="0" id="Test">
<aop:pointcut id="testPointcut" expression="execution(* aop..*(..))"/>
<aop:before pointcut-ref="testPointcut" method="beforeAdvice"/>
</aop:aspect>
</aop:config>
public class TestMain {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
People p = (People) ac.getBean("TestBean"); // 實際拿到的是代理物件
p.sayHello("傳入的參數值");
}
}
Console 輸出:
前置通知被觸發:aop.test.People將要sayHello
aop.test.People說:傳入的參數值
proxy-target-class="true":強制使用 CGLIB 代理(針對類而非介面)。expression="execution(* aop..*(..))":攔截 aop 套件下所有類別的所有方法。ProxyFactoryBean 取得 Bean 即為代理物件,透明植入切面邏輯。