4.4 在 XML 中声明切面

在 Spring 的 aop 命名空间中,提供了多个元素用来在 XML 中声明切面,如表 4.3 所示。

AOP 配置元素

用途

<aop:advisor>

定义 AOP 通知器

<aop:after>

定义 AOP 后置通知(不管被通知的方法是否执行成功)

<aop:after-returning>

定义 AOP 返回通知

<aop:after-throwing>

定义 AOP 异常通知

<aop:around>

定义 AOP 环绕通知

<aop:aspect>

定义一个切面

<aop:aspectj-autoproxy>

启用 @AspectJ 注解驱动的切面

<aop:before>

定义一个 AOP 前置通知

<aop:config>

顶层的 AOP 配置元素。大多数的元素必须包含在元素内

<aop:declare-parents>

以透明的方式为被通知的对象引入额外的接口

<aop:pointcut>

定义一个切点

我们已经看过了 <aop:aspectj-autoproxy> 元素,它能够自动代理 AspectJ 注解的通知类。aop 命名空间的其他元素能够让我们直接在 Spring 配置中声明切面,而不需要使用注解。

在本书前面的内容中,我曾经建立过这样一种原则,那就是基于注解的配置要优于基于 Java 的配置,基于 Java 的配置要优于基于 XML 的配置。但是,如果你需要声明切面,但是又不能为通知类添加注解的时候,那么就必须转向 XML 配置了。

在 Spring 的 aop 命名空间中,提供了多个元素用来在 XML 中声明切面,如表 4.3 所示。

AOP 配置元素

用途

<aop:advisor>

定义 AOP 通知器

<aop:after>

定义 AOP 后置通知(不管被通知的方法是否执行成功)

<aop:after-returning>

定义 AOP 返回通知

<aop:after-throwing>

定义 AOP 异常通知

<aop:around>

定义 AOP 环绕通知

<aop:aspect>

定义一个切面

<aop:aspectj-autoproxy>

启用 @AspectJ 注解驱动的切面

<aop:before>

定义一个 AOP 前置通知

<aop:config>

顶层的 AOP 配置元素。大多数的元素必须包含在元素内

<aop:declare-parents>

以透明的方式为被通知的对象引入额外的接口

<aop:pointcut>

定义一个切点

我们已经看过了 <aop:aspectj-autoproxy> 元素,它能够自动代理 AspectJ 注解的通知类。aop 命名空间的其他元素能够让我们直接在 Spring 配置中声明切面,而不需要使用注解。

例如,我们重新看一下 Audience 类,这一次我们将它所有的 AspectJ 注解全部移除掉:

package concert;
public class Audience {
public void silenceCellPhones() {
System.out.println("Silencing cell phones");
}
public void takeSeats() {
System.out.println("Taking seats");
}
public void applause() {
System.out.println("CLAP CLAP CLAP!!!");
}
public void demandRefund() {
System.out.println("Demanding a refund");
}
}

正如你所看到的,Audience 类并没有任何特别之处,它就是有几个方法的简单 Java 类。我们可以像其他类一样把它注册为 Spring 应用上下文中的 bean。

尽管看起来并没有什么差别,但 Audience 已经具备了成为 AOP 通知的所有条件。我们再稍微帮助它一把,它就能够成为预期的通知了。