搶佔先機
VMware 提供培訓和認證,以加速您的進步。
瞭解更多Spring AOP 中有很多新功能,包括 AspectJ 切入點語言、<aop:*/> 名稱空間和 @AspectJ 語法支援。 但到目前為止,最強大的方面(請原諒這個雙關語)之一是 AOP 上下文繫結。
例如,假設您想通知一個將 String 作為引數的方法。
public interface HelloService {
String getHelloMessage(String toAddHello);
}
要通知此方法,您需要編寫一個切入點,該切入點查詢 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 切入點語言。 這裡我們關心的部分是 args() 運算子。 此運算子允許我們選擇一個引數並將該引數繫結到我們的 advice。 因此,當切入點和 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!");
}
}
現在這非常酷。 您可以從通知的方法中獲得對引數的強型別和命名繫結到 advice 中。 在更復雜的示例中,可以繫結多個上下文片段,例如其他引數、正在呼叫的物件以及更多內容到 advice。 我想指出一件事,因為它總讓我絆倒,那就是 args() 運算子中的引數名稱對應於advice 方法中的引數名稱。
此特定配置的問題在於,大多數時候您不會建立帶有嵌入式切入點的 advice 宣告。 通常,您會將切入點外部化為命名切入點。 為此,您需要引入另一個級別的間接定址。 也就是說,命名切入點後跟 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!");
}
}
在此示例中需要注意的重要事項是,命名切入點需要將上下文型別作為引數,以便可以將該引數傳播到 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>
對於那些感興趣的人,我在此示例中提供了原始碼 就在這裡。