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