BeanNameAutoProxyCreator自動創建事務代理
用BeanNameAutoProxyCreator自動創建事務代理
下面介紹一種優秀的事務代理配置策略:采用這種配置策略,完全可以避免增量式配置,所有的事務代理由系統自動創建。容器中的目標bean自動消失,避免需要使用嵌套bean來保證目標bean不可被訪問。
這種配置方式依賴于Spring提供的bean后處理器,該后處理器用于為每個bean自動創建代理,此處的代理不僅可以是事務代理,也可以是任意的代理,只需要有合適的攔截器即可。這些是AOP框架的概念讀者只需了解這種事務代理的配置方式即可。
下面是采用BeanNameAutoProxyCreator配置事務代理的配置文件:
<?xml version="1.0" encoding="gb2312"?>
<!-- Spring配置文件的文件頭,包含DTD等信息-->
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"[url]http://www.springframework.org/dtd/spring-beans.dtd[/url]">
<beans>
<!--定義數據源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- 定義數據庫驅動-->
<property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
<!-- 定義數據庫url-->
<property name="url"><value>jdbc:mysql://localhost:3306/spring</value></property>
<!-- 定義數據庫用戶名-->
<property name="username"><value>root</value></property>
<!-- 定義數據庫密碼-->
<property name="password"><value>32147</value></property>
</bean>
<!--定義一個hibernate的SessionFactory-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 定義SessionFactory必須注入DataSource-->
<property name="dataSource"><ref local="dataSource"/></property>
<property name="mappingResources">
<list>
<!--以下用來列出所有的PO映射文件-->
<value>Person.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<!--此處用來定義hibernate的SessionFactory的屬性:
不同數據庫連接,啟動時選擇create,update,create-drop-->
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<!-- 定義事務管理器,使用適用于Hibernte的事務管理器-->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<!-- HibernateTransactionManager bean需要依賴注入一個SessionFactory bean的引用-->
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
下面介紹一種優秀的事務代理配置策略:采用這種配置策略,完全可以避免增量式配置,所有的事務代理由系統自動創建。容器中的目標bean自動消失,避免需要使用嵌套bean來保證目標bean不可被訪問。
這種配置方式依賴于Spring提供的bean后處理器,該后處理器用于為每個bean自動創建代理,此處的代理不僅可以是事務代理,也可以是任意的代理,只需要有合適的攔截器即可。這些是AOP框架的概念讀者只需了解這種事務代理的配置方式即可。
下面是采用BeanNameAutoProxyCreator配置事務代理的配置文件:
<?xml version="1.0" encoding="gb2312"?>
<!-- Spring配置文件的文件頭,包含DTD等信息-->
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"[url]http://www.springframework.org/dtd/spring-beans.dtd[/url]">
<beans>
<!--定義數據源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- 定義數據庫驅動-->
<property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
<!-- 定義數據庫url-->
<property name="url"><value>jdbc:mysql://localhost:3306/spring</value></property>
<!-- 定義數據庫用戶名-->
<property name="username"><value>root</value></property>
<!-- 定義數據庫密碼-->
<property name="password"><value>32147</value></property>
</bean>
<!--定義一個hibernate的SessionFactory-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 定義SessionFactory必須注入DataSource-->
<property name="dataSource"><ref local="dataSource"/></property>
<property name="mappingResources">
<list>
<!--以下用來列出所有的PO映射文件-->
<value>Person.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<!--此處用來定義hibernate的SessionFactory的屬性:
不同數據庫連接,啟動時選擇create,update,create-drop-->
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<!-- 定義事務管理器,使用適用于Hibernte的事務管理器-->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<!-- HibernateTransactionManager bean需要依賴注入一個SessionFactory bean的引用-->
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
<!-- 配置事務攔截器-->
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<!-- 事務攔截器bean需要依賴注入一個事務管理器 -->
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<!-- 下面定義事務傳播屬性-->
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<!-- 定義BeanNameAutoProxyCreator,該bean是個bean后處理器,無需被引用,因此沒有id屬性
這個bean后處理器,根據事務攔截器為目標bean自動創建事務代理
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
指定對滿足哪些bean name的bean自動生成業務代理 -->
<property name="beanNames">
<!-- 下面是所有需要自動創建事務代理的bean-->
<list>
<value>personDao</value>
</list>
<!-- 此處可增加其他需要自動創建事務代理的bean-->
</property>
<!-- 下面定義BeanNameAutoProxyCreator所需的事務攔截器-->
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
<!-- 此處可增加其他新的Interceptor -->
</list>
</property>
</bean>
<!--定義DAO Bean ,由于BeanNameAutoProxyCreator自動生成事務代理-->
<bean id="personDao" class="lee.PersonDaoHibernate">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
</beans>
TranscationInterceptor是一個事務攔截器bean,需要傳入一個TransactionManager的引用。配置中使用Spring依賴注入該屬性,事務攔截器的事務屬性通過transactionAttributes來指定,該屬性有props子元素,配置文件中定義了三個事務傳播規則:
所有以insert開始的方法,采用PROPAGATION_REQUIRED的事務傳播規則。程序拋出MyException異常及其子異常時,自動回滾事務。所有以find開頭的方法,采用PROPAGATION_REQUIRED事務傳播規則,并且只讀。其他方法,則采用PROPAGATION_REQUIRED的事務傳播規則。
BeanNameAutoProxyCreator是個根據bean名生成自動代理的代理創建器,該bean通常需要接受兩個參數。第一個是beanNames屬性,該屬性用來設置哪些bean需要自動生成代理。另一個屬性是interceptorNames,該屬性則指定事務攔截器,自動創建事務代理時,系統會根據這些事務攔截器的屬性來生成對應的事務代理。
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<!-- 事務攔截器bean需要依賴注入一個事務管理器 -->
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<!-- 下面定義事務傳播屬性-->
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<!-- 定義BeanNameAutoProxyCreator,該bean是個bean后處理器,無需被引用,因此沒有id屬性
這個bean后處理器,根據事務攔截器為目標bean自動創建事務代理
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
指定對滿足哪些bean name的bean自動生成業務代理 -->
<property name="beanNames">
<!-- 下面是所有需要自動創建事務代理的bean-->
<list>
<value>personDao</value>
</list>
<!-- 此處可增加其他需要自動創建事務代理的bean-->
</property>
<!-- 下面定義BeanNameAutoProxyCreator所需的事務攔截器-->
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
<!-- 此處可增加其他新的Interceptor -->
</list>
</property>
</bean>
<!--定義DAO Bean ,由于BeanNameAutoProxyCreator自動生成事務代理-->
<bean id="personDao" class="lee.PersonDaoHibernate">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
</beans>
TranscationInterceptor是一個事務攔截器bean,需要傳入一個TransactionManager的引用。配置中使用Spring依賴注入該屬性,事務攔截器的事務屬性通過transactionAttributes來指定,該屬性有props子元素,配置文件中定義了三個事務傳播規則:
所有以insert開始的方法,采用PROPAGATION_REQUIRED的事務傳播規則。程序拋出MyException異常及其子異常時,自動回滾事務。所有以find開頭的方法,采用PROPAGATION_REQUIRED事務傳播規則,并且只讀。其他方法,則采用PROPAGATION_REQUIRED的事務傳播規則。
BeanNameAutoProxyCreator是個根據bean名生成自動代理的代理創建器,該bean通常需要接受兩個參數。第一個是beanNames屬性,該屬性用來設置哪些bean需要自動生成代理。另一個屬性是interceptorNames,該屬性則指定事務攔截器,自動創建事務代理時,系統會根據這些事務攔截器的屬性來生成對應的事務代理。