# 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 值。默认设置是无序的。
