使用“自动代理”功能

到目前为止,我们已经考虑了使用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>

ProxyFactoryBean一样,它有一个interceptorNames属性而不是拦截器列表,以允许原型顾问正确工作。“命名”拦截器可以是顾问或任何建议类型。

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

名称匹配的bean定义,例如前面示例中的jdkMyBeanonlyJdk,是具有目标类的普通bean定义。AOP代理由BeanNameAutoProxyCreator自动创建。相同的建议应用于所有匹配的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"/>

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

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