# 6.8. 使用“自动代理”工具

到目前为止，我们已经考虑过使用`ProxyFactoryBean`或类似的工厂 bean 显式创建 AOP 代理。

Spring 还允许我们使用“自动代理”bean 定义，它可以自动代理选定的 bean 定义。这是建立在 Spring 的“bean 后处理器”基础设施之上的，它可以在容器加载时修改任何 bean 定义。

在这个模型中，您在 XML bean 定义文件中设置了一些特殊的 bean 定义来配置自动代理基础设施。这使您可以声明符合自动代理条件的目标。你不需要使用`ProxyFactoryBean`.

有两种方法可以做到这一点：

* 通过使用在当前上下文中引用特定 bean 的自动代理创建者。
* 一个值得单独考虑的自动代理创建的特殊情况：由源级元数据属性驱动的自动代理创建。

**6.8.1. 自动代理 Bean 定义**

本节介绍 `org.springframework.aop.framework.autoproxy`包提供的自动代理创建者。

**`BeanNameAutoProxyCreator`**

`BeanNameAutoProxyCreator`类是一个`BeanPostProcessor`，会自动为名称与文字值或通配符匹配的 bean 创建 AOP 代理。以下示例显示了如何创建`BeanNameAutoProxyCreator`bean：

```xml
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
    <property name="beanNames" value="jdk*,onlyJdk"/>
    <property name="interceptorNames">
        <list>
            <value>myInterceptor</value>
        </list>
    </property>
</bean>
```

与 `ProxyFactoryBean`一样，有一个`interceptorNames`属性而不是拦截器列表，以允许原型Advisor的正确行为。命名为“拦截器”可以是Advisor或任何切面类型。

与一般的自动代理一样，使用`BeanNameAutoProxyCreator`的主要目的是将相同的配置一致地应用于多个对象，并且配置量最少。将声明性事务应用于多个对象是一种流行的选择。

名称匹配的 Bean 定义（例如前面示例中的 jdkMyBean 和 onlyJdk）是带有目标类的普通旧式 Bean 定义。 AOP 代理由 BeanNameAutoProxyCreator 自动创建。 相同的切面适用于所有匹配的 bean。请注意，如果使用了Advisor（而不是前面示例中的拦截器），则切入点可能会以不同的方式应用于不同的 bean。

**`DefaultAdvisorAutoProxyCreator`**

一个更通用且极其强大的自动代理创建者是 `DefaultAdvisorAutoProxyCreator`. 这会自动在当前上下文中应用符合条件的Advisor，而无需在自动代理Advisor的 bean 定义中包含特定的 bean 名称。它提供了与 `BeanNameAutoProxyCreator` 相同的配置一致和避免重复的优点。

使用此机制涉及：

* 指定`DefaultAdvisorAutoProxyCreator`bean 定义。
* 在相同或相关的上下文中指定任意数量的Advisor。请注意，这些必须是Advisor，而不是拦截器或其他切面。这是必要的，因为必须有一个切入点来评估，以检查每个切面对候选 bean 定义的资格。

`DefaultAdvisorAutoProxyCreator`自动评估每个Advisor中包含的切入点，以查看它应该对每个业务对象应用什么（如果有）切面（例如`businessObject1`和`businessObject2`示例中的）。

这意味着可以将任意数量的Advisor自动应用于每个业务对象。如果任何Advisor中没有切入点与业务对象中的任何方法匹配，则不会代理该对象。当为新业务对象添加 bean 定义时，它们会在必要时自动代理。

自动代理通常具有使调用者或依赖项无法获得不切面的对象的优点。调用`ApplicationContext`的`getBean("businessObject1")`会返回一个 AOP 代理，而不是目标业务对象。（前面显示的“inner bean”习语也提供了这个好处。）

以下示例创建一个`DefaultAdvisorAutoProxyCreator`bean 和本节中讨论的其他元素：

```xml
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>

<bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
    <property name="transactionInterceptor" ref="transactionInterceptor"/>
</bean>

<bean id="customAdvisor" class="com.mycompany.MyAdvisor"/>

<bean id="businessObject1" class="com.mycompany.BusinessObject1">
    <!-- Properties omitted -->
</bean>

<bean id="businessObject2" class="com.mycompany.BusinessObject2"/>
```

如果您想将相同的切面一致地应用于许多业务对象，`DefaultAdvisorAutoProxyCreator`非常有用。一旦基础设施定义到位，您就可以添加新的业务对象，而无需包括特定的代理配置。您还可以轻松地添加其他方面（例如，跟踪或性能监控方面），而只需对配置进行最少的更改。

`DefaultAdvisorAutoProxyCreator`提供对过滤（通过使用命名约定以便仅评估某些Advisor，这允许在同一工厂中使用多个不同配置的 AdvisorAutoProxyCreators）和排序的支持。如果这是一个问题，Advisor可以实现该`org.springframework.core.Ordered`接口以确保正确排序。前面示例中使用的`TransactionAttributeSourceAdvisor` 具有可配置的 order 值。默认设置是无序的。


---

# 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://doc.shiker.tech/spring-he-xin-gong-neng/6.-spring-aop-api/6.8.-shi-yong-zi-dong-dai-li-gong-ju.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.
