4.4.1 声明前置和后置通知
你可以再把那些 AspectJ 注解加回来,但这并不是本节的目的。相反,我们会使用 Spring aop 命名空间中的一些元素,将没有注解的 Audience 类转换为切面。下面的程序展示了所需要的 XML。
关于 Spring AOP 配置元素,第一个需要注意的事项是大多数的 AOP 配置元素必须在 <aop:config> 元素的上下文内使用。这条规则有几种例外场景,但是把 bean 声明为一个切面时,我们总是从 <aop:config> 元素开始配置的。
在 <aop:config> 元素内,我们可以声明一个或多个通知器、切面或者切点。在上述程序中,我们使用 <aop:aspect> 元素声明了一个简单的切面。ref 元素引用了一个 POJO bean,该 bean 实现了切面的功能 —— 在这里就是 audience。ref 元素所引用的 bean 提供了在切面中通知所调用的方法。
该切面应用了四个不同的通知。两个 <aop:before> 元素定义了匹配切点的方法执行之前调用前置通知方法,也就是 Audience bean 的 takeSeats() 和 turnOffCellPhones() 方法(由 method 属性所声明)。<aop:after-returning> 元素定义了一个返回(after-returning)通知,在切点所匹配的方法调用之后再调用 applaud() 方法。同样,元素定义了异常(after-throwing)通知,如果所匹配的方法执行时抛出任何的异常,都将会调用 demandRefund() 方法。图 4.8 展示了通知逻辑如何织入到业务逻辑中。
在所有的通知元素中,pointcut 属性定义了通知所应用的切点,它的值是使用 AspectJ 切点表达式语法所定义的切点。
你或许注意到所有通知元素中的 pointcut 属性的值都是一样的,这是因为所有的通知都要应用到相同的切点上。
在基于 AspectJ 注解的通知中,当发现这种类型的重复时,我们使用 @Pointcut 注解消除了这些重复的内容。而在基于 XML 的切面声明中,我们需要使用元素。如下的 XML 展现了如何将通用的切点表达式抽取到一个切点声明中,这样这个声明就能在所有的通知元素中使用了。
现在切点是在一个地方定义的,并且被多个通知元素所引用。<aop:pointcut> 元素定义了一个 id 为 performance 的切点。同时修改所有的通知元素,用 pointcut-ref 属性来引用这个命名切点。
正如上述程序所展示的,<aop:pointcut> 元素所定义的切点可以被同一个 <aop:aspect> 元素之内的所有通知元素引用。如果想让定义的切点能够在多个切面使用,我们可以把 <aop:pointcut> 元素放在 <aop:config> 元素的范围内。
Last updated