<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

<context:annotation-config />
    <context:component-scan base-package="com.*" />

<bean id="sessionFactory"  
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />  
        <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
    </bean>

<!-- 定义事务管理器(声明式的事务) -->  
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    
    <!-- 配置DAO -->
    <bean id="generatorDaoTarget" class="com.*.spring.dao.GeneratorDaoImpl">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    
    <bean id="generatorDao"  
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">  
        <!-- 配置事务管理器 -->  
        <property name="transactionManager"><ref bean="transactionManager" /></property>  
        <property name="target"><ref bean="generatorDaoTarget" /></property>  
        <property name="proxyInterfaces"><value>com.*.spring.dao.GeneratorDao</value></property>
        <!-- 配置事务属性 -->  
        <property name="transactionAttributes">  
            <props>  
                <prop key="*">PROPAGATION_REQUIRED</prop>
            </props>  
        </property>  
    </bean>

<bean id="plantDaoTarget" class="com.*.spring.dao.PlantDaoImpl">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    
    <bean id="plantDao"  
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">  
           <!-- 配置事务管理器 -->  
        <property name="transactionManager"><ref bean="transactionManager" /></property>     
        <property name="target"><ref bean="plantDaoTarget" /></property> 
        <property name="proxyInterfaces"><value>com.*.spring.dao.PlantDao</value></property>           
        <!-- 配置事务属性 -->  
        <property name="transactionAttributes">  
            <props>  
                <prop key="*">PROPAGATION_REQUIRED</prop>
            </props>  
        </property>  
    </bean>
    
    <!-- 配置Service -->
    <bean id="plantGeneratorServiceTarget"  
        class="com.*.spring.service.PlantGeneratorServiceImpl">  
        <property name="plantDao">  
            <ref bean="plantDao" />  
        </property>  
        <property name="generatorDao">  
            <ref bean="generatorDao" />  
        </property>  
    </bean>        
    
    <bean id="plantGeneratorService"  
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">  
           <!-- 配置事务管理器 -->  
           <property name="transactionManager"><ref bean="transactionManager" /></property>     
        <property name="target"><ref bean="plantGeneratorServiceTarget" /></property>  
        <property name="proxyInterfaces"><value>com.*.spring.service.PlantGeneratorService</value></property>
        <!-- 配置事务属性 -->  
        <property name="transactionAttributes">  
            <props>  
                <prop key="*">PROPAGATION_REQUIRED</prop>  
            </props>  
        </property>  
    </bean>  
</beans>

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>

<!-- 各属性的配置-->
    <!-- 为true表示将Hibernate发送给数据库的sql显示出来 -->
    <property name="hibernate.show_sql">true</property>
    <property name="hibernate.hbm2ddl.auto">none</property>

<!-- SQL方言,这边设定的是MySQL -->
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    <!--连接数据库的Driver-->
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    <!--数据库连接url-->
    <property name="connection.url">jdbc:mysql://localhost:3306/test</property>

<!--用户名-->
    <property name="connection.username">root</property>
    <!--密码-->
    <property name="connection.password">123456</property>

<!-- 映射文件  -->
    <mapping class="com.*.spring.domain.Generator" />
    <mapping class="com.*.spring.domain.Plant" />
</session-factory>
</hibernate-configuration>

public interface GeneratorDao {

/**
     * 获取所有机组数据
     * @return
     */
    public List<Generator> listGenerators();
    
    /**
     * 保存机组数据
     * @param generator 机组数据
     */
    public void save(Generator generator);    
}

public class GeneratorDaoImpl extends HibernateDaoSupport implements GeneratorDao {
       
    @SuppressWarnings("unchecked")
    public List<Generator> listGenerators() {
        return this.getSession().createQuery("from Generator").list();
    }

public void save(Generator generator) {
        this.getSession().save(generator);    
    }
}

 --------------------------------------------------------------------------------------------------------------------------------------

通常建议采用声明式事务管理。声明式事务管理的优势非常明显:代码中无需关于关注事务逻辑,让Spring声明式事务管理负责事务逻辑,声明式事务管理无需与具体的事务逻辑耦合,可以方便地在不同事务逻辑之间切换。
声明式事务管理的配置方式,通常有如下三种:
1.使用TransactionProxyFactoryBean为目标bean生成事务代理的配置。此方式是最传统,配置文件最臃肿、难以阅读的方式。
2.采用bean继承的事务代理配置方式,比较简洁,但依然是增量式配置。
3.使用BeanNameAutoProxyCreator,根据bean name自动生成事务代理的方式,这是直接利用Spring的AOP框架配置事务代理的方式,需要对Spring的AOP框架有所理解。但这种方式避免了增量式配置,效果非常不错。
4.DefaultAdvisorAutoProxyCreator:这也是直接利用Spring的AOP框架配置事务代理的方式,效果也非常不多,只是这种配置方式的可读性不如第三种方式。

一. 利用TransactionProxyFactoryBean生成事务代理
采用这种方式的配置时候,配置文件的增加非常快,每个bean有需要两个bean配置,一个目标,另外还需要使用TransactionProxyFactoryBean配置一个代理bean。
这是一种最原始的配置方式,下面是使用TransactionProxyFactoryBean的配置文件:

  1. <?xml version="1.0" encoding="gb2312"?>
  2. <!--   Spring配置文件的文件头,包含DTD等信息-->
  3. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
  4. "http://www.springframework.org/dtd/spring-beans.dtd">
  5. <beans>
  6. <!--定义数据源-->
  7. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  8. <!--   定义数据库驱动-->
  9. <property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
  10. <!--   定义数据库url-->
  11. <property name="url"><value>jdbc:mysql://localhost:3306/spring</value></property>
  12. <!--   定义数据库用户名-->
  13. <property name="username"><value>root</value></property>
  14. <!--   定义数据库密码-->
  15. <property name="password"><value>32147</value></property>
  16. </bean>
  17. <!--定义一个hibernate的SessionFactory-->
  18. <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  19. <!--   定义SessionFactory必须注入DataSource-->
  20. <property name="dataSource"><ref local="dataSource"/></property>
  21. <property name="mappingResources">
  22. <list>
  23. <!--以下用来列出所有的PO映射文件-->
  24. <value>Person.hbm.xml</value>
  25. </list>
  26. </property>
  27. <property name="hibernateProperties">
  28. <props>
  29. <!--此处用来定义hibernate的SessionFactory的属性:
  30. 不同数据库连接,启动时选择create,update,create-drop-->
  31. <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
  32. <prop key="hibernate.hbm2ddl.auto">update</prop>
  33. </props>
  34. </property>
  35. </bean>
  36. <!--   定义事务管理器,使用适用于Hibernte的事务管理器-->
  37. <bean id="transactionManager"
  38. class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  39. <!--   HibernateTransactionManager   bean需要依赖注入一个SessionFactory bean的引用-->
  40. <property name="sessionFactory"><ref local="sessionFactory"/></property>
  41. </bean>
  42. <!--定义DAO Bean , 作为事务代理的目标-->
  43. <bean id="personDaoTarget" class="lee.PersonDaoHibernate">
  44. <!--   为DAO bean注入SessionFactory引用-->
  45. <property name="sessionFactory"><ref local="sessionFactory"/></property>
  46. </bean>
  47. <!--   定义DAO bean的事务代理-->
  48. <bean id="personDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
  49. <!--   为事务代理bean注入事务管理器-->
  50. <property name="transactionManager"><ref bean="transactionManager"/></property>
  51. <!--   设置事务属性-->
  52. <property name="transactionAttributes">
  53. <props>
  54. <!--   所有以find开头的方法,采用required的事务策略,并且只读-->
  55. <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
  56. <!--   其他方法,采用required的事务策略 ->
  57. <prop key="*">PROPAGATION_REQUIRED</prop>
  58. </props>
  59. </property>
  60. <!--   为事务代理bean设置目标bean -->
  61. <property name="target">
  62. <ref local="personDaoTarget"/>
  63. </property>
  64. </bean>
  65. </beans>

在上面的配置文件中,personDao需要配置两个部分,一个是personDao的目标bean,该目标bean是实际DAO bean,以实际的DAO bean为目标,建立事务代理。一个组件,需要来个bean组成,一个目标bean,一个事务代理。
这种配置方式还有一个坏处:目标bean直接暴露在Spring容器中,可以直接引用,如果目标bean被误引用,将导致业务操作不具备事务性。
为了避免这种现象,可将目标bean配置成嵌套bean,下面是目标bean和事务代理的配置片段:

  1. <!--   定义DAO bean的事务代理-->
  2. <bean id="personDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
  3. <!--   为事务代理bean注入事务管理器-->
  4. <property name="transactionManager"><ref bean="transactionManager"/></property>
  5. <!--   设置事务属性-->
  6. <property name="transactionAttributes">
  7. <props>
  8. <!--   所有以find开头的方法,采用required的事务策略,并且只读-->
  9. <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
  10. <!--   其他方法,采用required的事务策略 ->
  11. <prop key="*">PROPAGATION_REQUIRED</prop>
  12. </props>
  13. </property>
  14. <!--   为事务代理bean设置目标bean -->
  15. <property name="target">
  16. <!--   采用嵌套bean配置目标bean-->
  17. <bean class="lee.PersonDaoHibernate">
  18. <!--   为DAO bean注入SessionFactory引用-->
  19. <property name="sessionFactory"><ref local="sessionFactory"/></property>
  20. </bean>
  21. </property>
  22. </bean>

二. 利用继承简化配置
大部分情况下,每个事务代理的事务属性大同小异,事务代理的实现类都是TransactionProxyFactoryBean,事务代理bean都必须注入事务管理器。
对于这种情况,Spring提供了bean与bean之间的继承,可以简化配置。将大部分的通用配置,配置成事务模板,而实际的事务代理bean,则继承事务模板。这种配置方式可以减少部分配置代码,下面是采用继承的配置文件:

s

  1. <?xml version="1.0" encoding="gb2312"?>
  2. <!--   Spring配置文件的文件头,包含DTD等信息-->
  3. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
  4. "http://www.springframework.org/dtd/spring-beans.dtd">
  5. <beans>
  6. <!--定义数据源-->
  7. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  8. <!--   定义数据库驱动-->
  9. <property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
  10. <!--   定义数据库url-->
  11. <property name="url"><value>jdbc:mysql://localhost:3306/spring</value></property>
  12. <!--   定义数据库用户名-->
  13. <property name="username"><value>root</value></property>
  14. <!--   定义数据库密码-->
  15. <property name="password"><value>32147</value></property>
  16. </bean>
  17. <!--定义一个hibernate的SessionFactory-->
  18. <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  19. <!--   定义SessionFactory必须注入DataSource-->
  20. <property name="dataSource"><ref local="dataSource"/></property>
  21. <property name="mappingResources">
  22. <list>
  23. <!--以下用来列出所有的PO映射文件-->
  24. <value>Person.hbm.xml</value>
  25. </list>
  26. </property>
  27. <property name="hibernateProperties">
  28. <props>
  29. <!--此处用来定义hibernate的SessionFactory的属性:
  30. 不同数据库连接,启动时选择create,update,create-drop-->
  31. <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
  32. <prop key="hibernate.hbm2ddl.auto">update</prop>
  33. </props>
  34. </property>
  35. </bean>
  36. <!--   定义事务管理器,使用适用于Hibernte的事务管理器-->
  37. <bean id="transactionManager"
  38. class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  39. <!--   HibernateTransactionManager   bean需要依赖注入一个SessionFactory bean的引用-->
  40. <property name="sessionFactory"><ref local="sessionFactory"/></property>
  41. </bean>
  42. <!-- 配置事务模板,模板bean被设置成abstract bean,保证不会被初始化-->
  43. <bean id="txBase" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
  44. lazy-init="true" abstract="true">
  45. <!--   为事务模板注入事务管理器-->
  46. <property name="transactionManager"><ref bean="transactionManager"/></property>
  47. <!--   设置事务属性-->
  48. <property name="transactionAttributes">
  49. <props>
  50. <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
  51. <prop key="*">PROPAGATION_REQUIRED</prop>
  52. </props>
  53. </property>
  54. </bean>
  55. <!--   实际的事务代理bean-->
  56. <bean id="personDao" parent="txBase">
  57. <!--   采用嵌套bean配置目标bean -->
  58. <property name="target">
  59. <bean class="lee.PersonDaoHibernate">
  60. <property name="sessionFactory"><ref local="sessionFactory"/></property>
  61. </bean>
  62. </property>
  63. </bean>
  64. </beans>

这种配置方式,相比前面直接采用TransactionProxyFactoryBean的事务代理配置方式,可以大大减少配置文件的代码量。每个事务代理的配置都继承事务模板,无需重复指定事务代理的实现类,无需重复指定事务传播属性——当然,如果新的事务代理有额外的事务属性,也可指定自己的事务属性,此时,子bean的属性覆盖父bean的属性。当然每个事务代理bean都必须配置自己的目标bean,这不可避免。
上面的配置可看出,事务代理的配置依然是增量式的,每个事务代理都需要单独配置——虽然增量已经减少,但每个事务代理都需要单独配置。

 
 
 
 

最新文章

  1. uboot环境配置
  2. QSS的应用
  3. java从0开始学——数组,一维和多维
  4. SQL数据类型大全 《转自网络》
  5. iOS应用的真机调试
  6. Owasp Top 10 Security Risks for 2014
  7. sqrt 源代码
  8. JavaScript等比例缩放图片
  9. 代码创建 WPF 旋转动画
  10. 解决java.lang.NumberFormatException: For input string: &quot;id&quot;
  11. 对X86汇编的理解与入门
  12. C++ UI资源
  13. dojo实现省份地市级联报错(二)
  14. 【XSY3320】string AC自动机 哈希 点分治
  15. 做了面向互联网部署的Dynamics 365 CE更改AD FS的登录页面
  16. Flask学习笔记(3)--路由
  17. flask 在模板中渲染表单
  18. Eclipse中出现无法找到Maven包Active Maven Profiles (comma separated)
  19. maven 使用之自动编译热部署设置
  20. [Apio2012]dispatching 主席树做法

热门文章

  1. 剑指offer24 二叉搜索树的后序遍历序列
  2. python_83_random_应用验证码
  3. appium---启动app
  4. 瀑布流封装(仿写UITableView)
  5. Python基础——赋值机制
  6. python中的内建函数
  7. Android自动化测试如何获取坐标点?
  8. 装饰器与lambda
  9. python面试题解析(数据库和缓存)
  10. webdriver高级应用- 使用Chrome浏览器自动将文件下载到指定路径