So far we've looked at explicitly creating an AOP proxy using a ProxyFactoryBean or similar factory bean.

Spring also allows us to use "auto-proxy" bean definitions, which can automatically proxy selected bean definitions. This principle is built on Spring's "bean postprocessor" infrastructure, which allows any bean definition to be modified as the container loads.

In this model, you set some specific bean definitions in your XML bean definition file to configure the auto-proxy infrastructure. This allows you to declare targets that are suitable for auto-proxying. There is no need to use ProxyFactoryBean.

You can do this in two ways:

  • Using an auto-proxy creator that references specific beans in the current context.

  • A special case of auto-proxy creation that deserves special consideration: creating an auto-proxy based on source-level metadata attributes.

Bean definitions with auto-proxy

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

BeanNameAutoProxyCreator

The class BeanNameAutoProxyCreator 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 bean BeanNameAutoProxyCreator:

<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
    <property name="beanNames" value="jdk*,onlyJdk"/>
    <property name="interceptorNames">
        <list>
            <value>myInterceptor</value>
        </list>
    </property>
</bean>

As in ProxyFactoryBean, there is a interceptorNames property here, rather than a list of interceptors, to ensure the correct logic of the prototype advisors. Named "interceptors" can be advisors or advice of any type.

As with autoproxy in general, the main point of using the BeanNameAutoProxyCreator is to consistently apply the same configuration to multiple objects with minimal configuration. This is a popular way to apply declarative transactions to multiple objects.

Bean definitions that have the same name, such as jdkMyBean and onlyJdk in the previous example, are normal bean definitions with a target class. The AOP proxy is automatically created using BeanNameAutoProxyCreator. The same advice applies to all relevant beans. Note that if advisors are used (rather than the interceptor in the previous example), slices can be applied differently to different beans.

DefaultAdvisorAutoProxyCreator

A more common but extremely effective auto proxy creator is DefaultAdvisorAutoProxyCreator. It automatically applies the appropriate EAs in the current context, without the need to include specific bean names in the auto-proxy EA bean definition. It offers the same benefits of consistent configuration and duplication avoidance as BeanNameAutoProxyCreator.

Uses of this mechanism include:

  • Setting the bean definition DefaultAdvisorAutoProxyCreator.

  • Assigning any number of advisors in the same or adjacent contexts. Please note that these must be advisors and not interceptors or other advisories. This is necessary because a computed slice must exist to check that each tip matches the definitions of the candidate bins.

DefaultAdvisorAutoProxyCreator automatically calculates the slice contained in each advisor to know which advice (if any) it should apply to each business object (for example, businessObject1 and businessObject2 in the example).

This means that any number of advisors can be automatically applied to each business object. If none of the advisors match any method of the business object, the object will not be proxied. As bean definitions are added for new business objects, they are automatically proxied if necessary.

The advantage of autoproxy in general is that it prevents calling code or dependencies from obtaining an object that is not provided with advice. Calling getBean("businessObject1") on this ApplicationContext returns the AOP proxy, not the target business object. (The "inner bin" approach shown earlier also provides this benefit.)

The following example creates the 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 is very useful if you need to consistently apply the same advice to many business objects. Once infrastructure definitions are created, new business objects can be added without enabling a specific proxy configuration. You can also easily add additional aspects (such as tracing or performance monitoring aspects) with minimal configuration changes.

DefaultAdvisorAutoProxyCreator offers support for filtering (by using a naming convention so that only specific advisors are evaluated, allowing multiple differently configured AdvisorAutoProxyCreators to be used in the same factory) and ordering. Advisors can implement the org.springframework.core.Ordered interface to ensure proper ordering if this is an issue. The TransactionAttributeSourceAdvisor used in the previous example has a custom ordering value. The default is "unordered".