搶先一步
VMware 提供培訓和認證,以加速您的進度。
了解更多Spring AOP 中有大量新功能,包括 AspectJ pointcut 語言、<aop:*/> 命名空間和 @AspectJ 語法支援。 但到目前為止,最強大的方面之一(請原諒這個雙關語)是 AOP 環境綁定。
例如,假設您想要建議一個以 String 作為引數的方法。
public interface HelloService {
String getHelloMessage(String toAddHello);
}
為了建議這個方法,您需要撰寫一個 pointcut,尋找 String 回傳型別、HelloService 介面的所有實作和 getHelloMessage(String) 方法。
@Before("execution(public java.lang.String aop.HelloService+.getHelloMessage(String))")
但如果您想要套用一個需要在內部使用該 String 引數的 advice 呢?
public void filter(String input) {
if (obscenities.contains(input)) {
throw new IllegalArgumentException("Obscenities such as '" + input + "' will not be tolerated!");
}
}
這就是 AOP 環境綁定發揮作用的地方。 原來 Spring 支援相當多的 AspectJ pointcut 語言。 此處與我們相關的部分是 args() 運算子。 這個運算子允許我們選取一個引數,並將該引數繫結到我們的 advice。 因此,當 pointcut 和 advice 結合時,您會看到如下所示的內容。
@Before("execution(public java.lang.String aop.HelloService+.getHelloMessage(String)) && args(input)")
public void filter(String input) {
if (obscenities.contains(input)) {
throw new IllegalArgumentException("Obscenities such as '" + input + "' will not be tolerated!");
}
}
這非常酷。 您可以從 advised 方法到 advice 獲得引數的強型別和具名繫結。 在更複雜的範例中,也可以將多個環境資訊片段(例如其他引數、正在呼叫的物件等)繫結到 advice。 我要指出的一件事是,它一直困擾著我,args() 運算子中的引數名稱對應於advice 方法中引數的名稱。
此特定組態的問題在於,大多數時候您不會建立具有內嵌 pointcut 的 advice 宣告。 通常您會將 pointcut 外部化為具名 pointcut。 為此,您需要引入另一個間接層級。 也就是說,具名 pointcut 後面接著 advice 定義。
@Pointcut("execution(public java.lang.String aop.HelloService+.getHelloMessage(String)) && args(helloInput)")
public void helloService(String helloInput) {}
@Before("helloService(input)")
public void filter(String input) {
if (obscenities.contains(input)) {
throw new IllegalArgumentException("Obscenities such as '" + input + "' will not be tolerated!");
}
}
在此範例中,需要注意的重要一點是,具名 pointcut 必須將環境資訊的類型作為引數,以便將該引數傳播到 advice。 您可以看到 helloService(String) 採用 String,以便 Before advice 可以參考 helloService(input)。
最後一步是建立一個將系統連接在一起的組態檔。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.0.xsd">
<bean id="helloService" class="aop.HelloServiceImpl" />
<bean id="obscenityFilter" class="aop.ObscenityFilter">
<constructor-arg>
<util:set>
<value>Microsoft</value>
</util:set>
</constructor-arg>
</bean>
<aop:aspectj-autoproxy>
<aop:include name="obscenityFilter" />
</aop:aspectj-autoproxy>
</beans>
對於那些有興趣的人,我將這個範例的原始程式碼放在這裡 here.