使用“自动代理”功能

到目前为止,我们已经考虑了通过使用 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 支持过滤(通过使用命名约定, 以便只评估某些通知器,这允许在同一个工厂中使用多个、 不同配置的 AdvisorAutoProxyCreator)和排序。 通知器可以实现 org.springframework.core.Ordered 接口,以确保 在存在问题时进行正确的排序。前面示例中使用的 TransactionAttributeSourceAdvisor 具有可配置的排序值。默认设置为无序。