領先一步
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 引數的建議呢?
public void filter(String input) {
if (obscenities.contains(input)) {
throw new IllegalArgumentException("Obscenities such as '" + input + "' will not be tolerated!");
}
}
嗯,這就是 AOP 上下文繫結的作用所在。事實上,Spring 支援相當多的 AspectJ 切點語言。這裡我們關心的是 args() 運算子。這個運算子允許我們選擇一個引數並將其繫結到我們的建議。所以,當切點和建議結合起來時,你會看到這樣的效果。
@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!");
}
}
現在這很酷。您可以從被建議的方法中強型別且命名地將引數繫結到建議。在更復雜的示例中,還可以將多個上下文片段(例如其他引數、正在呼叫的物件等)也繫結到建議。有一點我想強調一下,因為它總是讓我感到困惑:args() 運算子中的引數名稱對應於建議方法中的引數名稱。
此特定配置的問題在於,大多數時候您不會建立帶有嵌入式切點的建議宣告。通常,您會將切點外部化到一個命名切點。為此,您需要引入另一個間接層。也就是說,命名切點後跟建議定義。
@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!");
}
}
在此示例中要記下的重要事項是,命名切點需要將其上下文型別作為引數,以便可以將該引數傳播到建議。您可以看到 helloService(String) 接受一個 String,以便 Before 建議可以引用 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>
對於有興趣的人,我將在此示例中的原始碼 放在這裡。