Using the "auto-proxy" facility

到目前为止,我们已经考虑了使用 ProxyFactoryBean 或类似的工厂 Bean 显式创建 AOP 代理。

So far, we have considered explicit creation of AOP proxies by using a ProxyFactoryBean or similar factory bean.

Spring 还允许我们使用“自动代理”Bean 定义,它可以自动代理选定的 Bean 定义。这基于 Spring 的“Bean 后处理器”基础设施,它使容器加载时可以修改任何 Bean 定义。

Spring also lets us use “auto-proxy” bean definitions, which can automatically proxy selected bean definitions. This is built on Spring’s “bean post processor” infrastructure, which enables modification of any bean definition as the container loads.

在此模型中,您在 XML Bean 定义文件中设置一些特殊的 Bean 定义以配置自动代理基础设施。这允许您声明有资格进行自动代理的目标。您不必使用 ProxyFactoryBean。

In this model, you set up some special bean definitions in your XML bean definition file to configure the auto-proxy infrastructure. This lets you declare the targets eligible for auto-proxying. You need not use ProxyFactoryBean.

有两种方法可以做到这一点:

There are two ways to do this:

  • By using an auto-proxy creator that refers to specific beans in the current context.

  • A special case of auto-proxy creation that deserves to be considered separately: auto-proxy creation driven by source-level metadata attributes.

Auto-proxy Bean Definitions

本节介绍了 org.springframework.aop.framework.autoproxy 包提供的自动代理创建器。

This section covers the auto-proxy creators provided by the org.springframework.aop.framework.autoproxy package.

BeanNameAutoProxyCreator

BeanNameAutoProxyCreator 类是 BeanPostProcessor,它会自动为名称与特定值或通配符匹配的 bean 创建 AOP 代理。以下示例展示了如何创建 BeanNameAutoProxyCreator bean:

The BeanNameAutoProxyCreator class is a BeanPostProcessor that automatically creates AOP proxies for beans with names that match literal values or wildcards. The following example shows how to create a 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 属性,而不是拦截器列表,用于允许原型顾问正确运行。指定名称的“interceptor”可以是顾问或任何建议类型。

As with ProxyFactoryBean, there is an interceptorNames property rather than a list of interceptors, to allow correct behavior for prototype advisors. Named “interceptors” can be advisors or any advice type.

与一般的自动代理一样,使用 BeanNameAutoProxyCreator 的主要目的是对多个对象一致应用相同的配置,且使用最少的配置量。它是一款对多个对象应用声明式事务的热门选择。

As with auto-proxying in general, the main point of using BeanNameAutoProxyCreator is to apply the same configuration consistently to multiple objects, with minimal volume of configuration. It is a popular choice for applying declarative transactions to multiple objects.

名称匹配的 bean 定义(如前一个示例中的 jdkMyBeanonlyJdk)是带有目标类的普通老式 bean 定义。BeanNameAutoProxyCreator 会自动创建 AOP 代理。所有匹配的 bean 将应用相同的建议。请注意,如果您使用的是顾问(而不是前一个示例中的拦截器),那么切入点可能对不同的 bean 不同。

Bean definitions whose names match, such as jdkMyBean and onlyJdk in the preceding example, are plain old bean definitions with the target class. An AOP proxy is automatically created by the BeanNameAutoProxyCreator. The same advice is applied to all matching beans. Note that, if advisors are used (rather than the interceptor in the preceding example), the pointcuts may apply differently to different beans.

DefaultAdvisorAutoProxyCreator

更通用、功能极其强大的自动代理创建器是 DefaultAdvisorAutoProxyCreator。它会自动在当前上下文中应用合格的顾问,而无需在自动代理顾问的 bean 定义中包含特定 bean 名称。它与 BeanNameAutoProxyCreator 有着相同的一致性配置和避免重复的优点。

A more general and extremely powerful auto-proxy creator is DefaultAdvisorAutoProxyCreator. This automagically applies eligible advisors in the current context, without the need to include specific bean names in the auto-proxy advisor’s bean definition. It offers the same merit of consistent configuration and avoidance of duplication as BeanNameAutoProxyCreator.

使用此机制包括:

Using this mechanism involves:

  • Specifying a DefaultAdvisorAutoProxyCreator bean definition.

  • Specifying any number of advisors in the same or related contexts. Note that these must be advisors, not interceptors or other advice. This is necessary, because there must be a pointcut to evaluate, to check the eligibility of each advice to candidate bean definitions.

DefaultAdvisorAutoProxyCreator 会自动评估每个顾问中包含的切入点,以查看它应将哪些建议应用到每个业务对象(例如示例中的 businessObject1businessObject2)。

The DefaultAdvisorAutoProxyCreator automatically evaluates the pointcut contained in each advisor, to see what (if any) advice it should apply to each business object (such as businessObject1 and businessObject2 in the example).

这意味着可以对每个业务对象自动应用任意数量的建议。如果顾问中的任何切入点与业务对象中的任何方法都不匹配,那么不会代理该对象。在为新业务对象添加 bean 定义时,它们会在必要时自动代理。

This means that any number of advisors can be applied automatically to each business object. If no pointcut in any of the advisors matches any method in a business object, the object is not proxied. As bean definitions are added for new business objects, they are automatically proxied if necessary.

一般而言,自动代理带来的好处是不允许调用方或依赖项获取未得到建议的对象。对此 ApplicationContext 调用 getBean("businessObject1") 返回一个 AOP 代理,而不是目标业务对象。(前面显示的“innerbean”习惯用法也带来了此好处。)

Auto-proxying in general has the advantage of making it impossible for callers or dependencies to obtain an un-advised object. Calling getBean("businessObject1") on this ApplicationContext returns an AOP proxy, not the target business object. (The “inner bean” idiom shown earlier also offers this benefit.)

以下示例创建了一个 DefaultAdvisorAutoProxyCreator bean 以及本节中讨论的其他元素:

The following example creates a DefaultAdvisorAutoProxyCreator bean and the other elements discussed in this section:

<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 非常有用。基础设施定义就位后,您可以添加新的业务对象,而无需包含特定的代理配置。您还可以通过对配置进行最小的更改,轻松引入其他方面(比如,跟踪或性能监控方面)。

The DefaultAdvisorAutoProxyCreator is very useful if you want to apply the same advice consistently to many business objects. Once the infrastructure definitions are in place, you can add new business objects without including specific proxy configuration. You can also easily drop in additional aspects (for example, tracing or performance monitoring aspects) with minimal change to configuration.

DefaultAdvisorAutoProxyCreator 支持筛选(通过使用命名约定,以便仅评估某些顾问,它允许在同一工厂中使用多个但配置不同的 AdvisorAutoProxyCreators),还支持排序。顾问可以实现 org.springframework.core.Ordered 接口,以便在出现问题时确保正确的排序。在前一个示例中使用的 TransactionAttributeSourceAdvisor 有一个可配置的 order 值。默认设置是未排序。

The DefaultAdvisorAutoProxyCreator offers support for filtering (by using a naming convention so that only certain advisors are evaluated, which allows the use of multiple, differently configured, AdvisorAutoProxyCreators in the same factory) and ordering. Advisors can implement the org.springframework.core.Ordered interface to ensure correct ordering if this is an issue. The TransactionAttributeSourceAdvisor used in the preceding example has a configurable order value. The default setting is unordered.