Using the "auto-proxy" facility

到目前为止,我们已经考虑了使用 ProxyFactoryBean 或类似的工厂 Bean 显式创建 AOP 代理。 Spring 还允许我们使用“自动代理”Bean 定义,它可以自动代理选定的 Bean 定义。这基于 Spring 的“Bean 后处理器”基础设施,它使容器加载时可以修改任何 Bean 定义。 在此模型中,您在 XML Bean 定义文件中设置一些特殊的 Bean 定义以配置自动代理基础设施。这允许您声明有资格进行自动代理的目标。您不必使用 ProxyFactoryBean。 有两种方法可以做到这一点:

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

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

Auto-proxy Bean Definitions

本节介绍了 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>

ProxyFactoryBean 一样,这里有一个 interceptorNames 属性,而不是拦截器列表,用于允许原型顾问正确运行。指定名称的“interceptor”可以是顾问或任何建议类型。

与一般的自动代理一样,使用 BeanNameAutoProxyCreator 的主要目的是对多个对象一致应用相同的配置,且使用最少的配置量。它是一款对多个对象应用声明式事务的热门选择。

名称匹配的 bean 定义(如前一个示例中的 jdkMyBeanonlyJdk)是带有目标类的普通老式 bean 定义。BeanNameAutoProxyCreator 会自动创建 AOP 代理。所有匹配的 bean 将应用相同的建议。请注意,如果您使用的是顾问(而不是前一个示例中的拦截器),那么切入点可能对不同的 bean 不同。

DefaultAdvisorAutoProxyCreator

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

使用此机制包括:

  • 指定 DefaultAdvisorAutoProxyCreator bean 定义。

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

DefaultAdvisorAutoProxyCreator 会自动评估每个顾问中包含的切入点,以查看它应将哪些建议应用到每个业务对象(例如示例中的 businessObject1businessObject2)。

这意味着可以对每个业务对象自动应用任意数量的建议。如果顾问中的任何切入点与业务对象中的任何方法都不匹配,那么不会代理该对象。在为新业务对象添加 bean 定义时,它们会在必要时自动代理。

一般而言,自动代理带来的好处是不允许调用方或依赖项获取未得到建议的对象。对此 ApplicationContext 调用 getBean("businessObject1") 返回一个 AOP 代理,而不是目标业务对象。(前面显示的“innerbean”习惯用法也带来了此好处。)

以下示例创建了一个 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"/>

如果您想要将相同的建议一致地应用到多个业务对象,那么 DefaultAdvisorAutoProxyCreator 非常有用。基础设施定义就位后,您可以添加新的业务对象,而无需包含特定的代理配置。您还可以通过对配置进行最小的更改,轻松引入其他方面(比如,跟踪或性能监控方面)。

DefaultAdvisorAutoProxyCreator 支持筛选(通过使用命名约定,以便仅评估某些顾问,它允许在同一工厂中使用多个但配置不同的 AdvisorAutoProxyCreators),还支持排序。顾问可以实现 org.springframework.core.Ordered 接口,以便在出现问题时确保正确的排序。在前一个示例中使用的 TransactionAttributeSourceAdvisor 有一个可配置的 order 值。默认设置是未排序。