使用“自动代理”功能
到目前为止,我们已经讨论了使用 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
属性而不是拦截器列表,以便为原型 advisor 提供正确的行为。命名的“拦截器”可以是 advisor 或任何通知类型。
与一般的自动代理类似,使用 BeanNameAutoProxyCreator
的主要目的是以最少的配置量将相同的配置一致地应用于多个对象。它是将声明式事务应用于多个对象的常用选择。
名称匹配的 Bean 定义,例如前一个示例中的 jdkMyBean
和 onlyJdk
,是带有目标类的普通 bean 定义。BeanNameAutoProxyCreator
会自动创建 AOP 代理。相同的通知会应用于所有匹配的 bean。请注意,如果使用 advisor(而不是前一个示例中的拦截器),切入点可能会应用于不同的 bean。
DefaultAdvisorAutoProxyCreator
一个更通用且功能强大的自动代理创建器是 DefaultAdvisorAutoProxyCreator
。它会自动将当前上下文中的符合条件的 advisor 应用,而无需在自动代理 advisor 的 bean 定义中包含特定的 bean 名称。它与 BeanNameAutoProxyCreator
一样,提供了配置一致性和避免重复的优点。
使用此机制涉及
-
指定一个
DefaultAdvisorAutoProxyCreator
bean 定义。 -
在相同或相关的上下文中指定任意数量的 advisor。请注意,这些必须是 advisor,而不是拦截器或其他通知。这是必要的,因为必须有一个切入点来进行评估,以检查每个通知对候选 bean 定义的适用性。
DefaultAdvisorAutoProxyCreator
会自动评估每个 advisor 中包含的切入点,以查看应将哪些(如果有)通知应用于每个业务对象(例如示例中的 businessObject1
和 businessObject2
)。
这意味着可以将任意数量的 advisor 自动应用于每个业务对象。如果任何 advisor 中的切入点都不匹配业务对象中的任何方法,则该对象不会被代理。当为新的业务对象添加 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
支持过滤(通过命名约定,以便仅评估某些 advisor,这允许在同一个工厂中使用多个配置不同的 AdvisorAutoProxyCreator)和排序。Advisor 可以实现 org.springframework.core.Ordered
接口以确保正确的排序(如果这是一个问题)。前一个示例中使用的 TransactionAttributeSourceAdvisor
具有可配置的顺序值。默认设置是无序的。