BeanNameAutoProxyCreator,另一种声明方式TransactionProxyFactoryBean非常有用,当事 务代理包装对象时,它使你可以完全控制代理。如果你需要用一致的方式(例如,一个样板文件,“使所有的方法事务化”)包装大量的bean,使用一个 BeanFactoryPostProcessor的一个实现,BeanNameAutoProxyCreator,可以提供另外一种方法, 这个方法在这种简单的情况下更加简单。
重述一下,一旦ApplicationContext读完它的初始化信息,它将初始化所有实现BeanPostProcessor接口的bean,并且让它们后处理 ApplicationContext中所有其他的bean。所以使用这种机制,一个正确配置的BeanNameAutoProxyCreator可以用来后处 理所有ApplicationContext中所有其他的bean(通过名称来识别),并且把它 们用事务代理包装起来。真正生成的事务代理和使用 TransactionProxyFactoryBean生成的基本一致,这里不再 讨论。
让我们看下面的配置示例:
<!-- Transaction Interceptor set up to do PROPOGATION_REQUIRED on all methods -->
<bean id="matchAllWithPropReq"
class="org.springframework.transaction.interceptor.MatchAlwaysTransactionAttributeSource">
<property name="transactionAttribute"><value>PROPAGATION_REQUIRED</value></property>
</bean>
<bean id="matchAllTxInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager"><ref bean="transactionManager"/></property>
<property name="transactionAttributeSource"><ref bean="matchAllWithPropReq"/></property>
</bean>
<!-- One BeanNameAutoProxyCreator handles all beans where we want all methods to use
PROPOGATION_REQUIRED -->
<bean id="autoProxyCreator"
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="interceptorNames">
<list>
<idref local="matchAllTxInterceptor"/>
<idref bean="hibInterceptor"/>
</list>
</property>
<property name="beanNames">
<list>
<idref local="core-services-applicationControllerSevice"/>
<idref local="core-services-deviceService"/>
<idref local="core-services-authenticationService"/>
<idref local="core-services-packagingMessageHandler"/>
<idref local="core-services-sendEmail"/>
<idref local="core-services-userService"/>
</list>
</property>
</bean>
假设我们在ApplicationContext中已经有一个TransactionManager的实例 ,我们首先要做的使创建一个 TransactionInterceptor实例。 根据通过属性传递的TransactionAttributeSource接口的一个实现, ransactionInterceptor决定哪个 方法被拦截。这个例子中,我们希望处理匹配 所有方法这种最简单的情况。这个不是最有效的方式,但设置非常迅速,因为我可以使用预先定义的匹配所有方法的 MatchAlwaysTransactionAttributeSource类。如果我们需要特定的方式,可以使用 MethodMapTransactionAttributeSource, NameMatchTransactionAttributeSource或 AttributesTransactionAttributeSource。
现在我们已经有了事务拦截器,我们只需把它交给我们定义的 BeanNameAutoProxyCreator实例中,这样AppliactonContext中 定义的6个bean以同样的方式被封装。你可以看到,这比用TransactionProxyFactoryBean以一种方式单独封装6个bean简洁很 多。封装第7个bean只需添加一行配置。
你也许注意到可以应用多个拦截器。在这个例子中,我们还应用了一个 前面定义的HibernateInterceptor (bean id=hibInterceptor),它为我们管理 Hibernare的会话。
有一件事值得注意,就是在TransactionProxyFactoryBean, 和BeanNameAutoProxyCreator切换时bean的命名。第一种情况,你只需给你想要包装的bean一个类似myServiceTarget的id, 给代理对象一个类似myService的id,然后所有代理对象的用户只需引用代理对象,如myService(这些是通用命名规范,要点是目标对象要有和代理对象不同的名称,并且它们都要在ApplicationContext中可用)。然而,使用BeanNameAutoProxyCreator时, 你得命名目标对象为myService。然后当BeanNameAutoProxyCreator后处理目标对象 并生成代理时,它使得代理以和原始对象的名称被插入到 ApplicationContext中。从这一点看,只有代理(含有被包装的对象)在ApplicationContext中可用。




















