跳到主要内容

使用 "auto-proxy" 功能

ChatGPT-4o-mini 中英对照 Using the "auto-proxy" facility Using the "auto-proxy" facility

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

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

在这个模型中,您在 XML bean 定义文件中设置了一些特殊的 bean 定义,以配置自动代理基础设施。这使您可以声明适合自动代理的目标。您无需使用 ProxyFactoryBean

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

  • 通过使用一个自动代理创建器,该创建器引用当前上下文中的特定 bean。

  • 一个特殊的自动代理创建案例,值得单独考虑:由源级元数据属性驱动的自动代理创建。

自动代理 Bean 定义

本节涵盖了 org.springframework.aop.framework.autoproxy 包提供的自动代理创建器。

BeanNameAutoProxyCreator

BeanNameAutoProxyCreator 类是一个 BeanPostProcessor,它会自动为名称与字面值或通配符匹配的 bean 创建 AOP 代理。以下示例展示了如何创建一个 BeanNameAutoProxyCreator bean:

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

ProxyFactoryBean 一样,存在一个 interceptorNames 属性,而不是拦截器列表,以允许原型顾问的正确行为。被称为“拦截器”的可以是顾问或任何建议类型。

与一般的自动代理一样,使用 BeanNameAutoProxyCreator 的主要目的是以最小的配置量将相同的配置一致地应用于多个对象。它是将声明式事务应用于多个对象的一个流行选择。

与名称匹配的 Bean 定义,例如前面的示例中的 jdkMyBeanonlyJdk,是具有目标类的普通 Bean 定义。BeanNameAutoProxyCreator 会自动创建 AOP 代理。相同的建议适用于所有匹配的 Bean。请注意,如果使用顾问(而不是前面示例中的拦截器),切入点可能会对不同的 Bean 应用不同。

DefaultAdvisorAutoProxyCreator

一个更通用且功能强大的自动代理创建器是 DefaultAdvisorAutoProxyCreator。它会自动在当前上下文中应用合适的顾问,而无需在自动代理顾问的 bean 定义中包含特定的 bean 名称。它提供了与 BeanNameAutoProxyCreator 相同的优点,即一致的配置和避免重复。

使用此机制涉及:

  • 指定 DefaultAdvisorAutoProxyCreator bean 定义。

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

DefaultAdvisorAutoProxyCreator 会自动评估每个顾问中包含的切入点,以查看它应该对每个业务对象(例如示例中的 businessObject1businessObject2)应用什么(如果有的话)建议。

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

自动代理的一个优点是使调用者或依赖项无法获得未经过建议的对象。在这个 ApplicationContext 上调用 getBean("businessObject1") 返回的是一个 AOP 代理,而不是目标业务对象。(之前展示的“内部 bean”习惯用法也提供了这个好处。)

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

<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"/>
xml

DefaultAdvisorAutoProxyCreator 非常有用,如果你想将相同的建议一致地应用于许多业务对象。一旦基础设施定义到位,你可以添加新的业务对象,而无需包含特定的代理配置。你还可以轻松地添加额外的方面(例如,跟踪或性能监控方面),对配置的更改最小。

DefaultAdvisorAutoProxyCreator 提供了过滤支持(通过使用命名约定,使得只有某些顾问被评估,这允许在同一工厂中使用多个不同配置的 AdvisorAutoProxyCreators)和排序。如果排序是一个问题,顾问可以实现 org.springframework.core.Ordered 接口以确保正确的排序。在前面的示例中使用的 TransactionAttributeSourceAdvisor 具有可配置的顺序值。默认设置是无序的。