抢占先机
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>
对于那些感兴趣的人,我在此示例中提供了源代码 就在这里。