领先一步
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>
对于感兴趣的人,我在这个例子中提供了源代码在这里。