> For the complete documentation index, see [llms.txt](https://potoyang.gitbook.io/spring-in-action-v4/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://potoyang.gitbook.io/spring-in-action-v4/untitled/untitled-2.md).

# 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 注解全部移除掉：

```java
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 通知的所有条件。我们再稍微帮助它一把，它就能够成为预期的通知了。
