使用“自动代理”功能
到目前为止,我们已经考虑了通过使用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定义(例如前面示例中的jdkMyBean
和onlyJdk
)是具有目标类的普通旧bean定义。BeanNameAutoProxyCreator
会自动创建AOP代理。相同的建议将应用于所有匹配的bean。请注意,如果使用顾问(而不是前面示例中的拦截器),则切入点可能会以不同方式应用于不同的bean。
DefaultAdvisorAutoProxyCreator
一个更通用且非常强大的自动代理创建器是DefaultAdvisorAutoProxyCreator
。它会自动在当前上下文中应用符合条件的顾问,而无需在自动代理顾问的bean定义中包含特定的bean名称。它提供了与BeanNameAutoProxyCreator
相同的一致配置和避免重复的优点。
使用此机制涉及以下步骤:
-
指定一个
DefaultAdvisorAutoProxyCreator
bean定义。 -
在相同或相关上下文中指定任意数量的顾问。请注意,这些必须是顾问,而不是拦截器或其他建议。这是必要的,因为必须有一个切入点来评估,以检查每个建议对候选bean定义的资格。
DefaultAdvisorAutoProxyCreator
会自动评估每个顾问中包含的切入点,以查看应该将哪些(如果有)建议应用于每个业务对象(例如示例中的businessObject1
和businessObject2
)。
这意味着任意数量的顾问可以自动应用于每个业务对象。如果任何顾问中的任何切入点都不匹配业务对象中的任何方法,则不会对该对象进行代理。当为新的业务对象添加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
具有可配置的顺序值。默认设置是无序的。