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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://potoyang.gitbook.io/spring-in-action-v4/untitled/untitled-2.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
