领先一步
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>
对于有兴趣的人,我将在此示例中的源代码 放在这里。