`
winneryj
  • 浏览: 128605 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Spring事务简化配置

阅读更多
Java代码 复制代码

 

<beans>
	<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
    <bean id="transactionManager"
          class="org.springframework.orm.hibernate3.HibernateTransactionManager">
          <property name="sessionFactory">
              <ref bean="sessionFactory"/>
          </property>
    </bean>	
	
	<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
    	<property name="transactionManager" ref="transactionManager"/>
		<property name="transactionAttributeSource">
		  <value>
			com.skyon.user.manager.UserManager.*=PROPAGATION_REQUIRED
			#Add new defines here ->
		  </value>
		</property>
	</bean>
	
	<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
		<property name="interceptorNames">
			<list>
				<value>transactionInterceptor</value>
				<!--
				增加新的 Interceptor
				-->
			</list>
		</property>
	</bean>

	<bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
	  <property name="transactionInterceptor" ref="transactionInterceptor"/>
	</bean>
		
</beans>



这里利用 DefaultAdvisorAutoProxyCreator 实现了对容器中所有 bean 的自动代理,  增加一个需要事务的业务 bean 时只要在 transactionInterceptor 增加一行即可,  增加别的 interceptor 也非常方便,
极大减少了配置量

使得bean注入简捷的autowire,使得创建proxy简捷的autoproxy(实现有两个,一个是DefaultAdvisorAutoProxyCreator,BeanNameAutoProxyCreator).
另外一些奇技淫巧可以查下实现了BeanPostProcessor接口的类.

 

配置Spring,针对Service层的bean做事务处理,以往的做法是这样:

Java代码 复制代码

 

<bean id="txProxyTemplate" abstract="true" 
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 
    <property name="transactionManager">
        <ref bean="transactionManager"/>
    </property> 
    <property name="transactionAttributes"> 
        <props>
            <prop key="find*">PROPAGATION_REQUIRED, readOnly</prop> 
            <prop key="*">PROPAGATION_REQUIRED</prop> 
        </props> 
    </property> 
</bean> 

<bean id="userManager" parent="txProxyTemplate"> 
    <property name="target"> 
        <bean class="some.package.UserManagerImpl"> 
            <property name="userDAO"><ref bean="userDAO"/></property> 
        </bean> 
    </property> 
</bean> 



以后,如果增加新的Service/Manager,则XML配置的增量是这一段:

Java代码 复制代码

 

<bean id="someOtherManager" parent="txProxyTemplate"> 
    <property name="target"> 
        <bean class="some.package.someOtherManagerImpl"> 
        </bean> 
    </property> 
</bean> 



上面说的是老的做法,比较传统。缺点是增量比较大,配置起来copy&paste让人觉得不太爽,比较臃肿。

下面的是Feiing给出的更好的方案,我有一些修改:

Java代码 复制代码

 

<beans> 
        <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA); --> 
    <bean id="transactionManager"           class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
          <property name="sessionFactory"> 
              <ref bean="sessionFactory"/> 
          </property> 
    </bean>        
        
        <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"> 
            <property name="transactionManager" ref="transactionManager"/> 
            <property name="transactionAttributes">
                <props>
                    <prop key="*">PROPAGATION_REQUIRED</prop>
                    <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
                </props>
            </property>
        </bean> 
        
        <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> 
                <property name="beanNames">
                    <value>*Service,*Manager</value>
                </property>
                <property name="interceptorNames"> 
                        <list> 
                                <value>transactionInterceptor</value> 
                                <!-- 
                                此处增加新的Interceptor
                                --> 
                        </list> 
                </property> 
        </bean> 

        <bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor"> 
          <property name="transactionInterceptor" ref="transactionInterceptor"/> 
        </bean> 


        <bean id="userManager" class="some.package.UserManagerImpl" autoWire="byName"/>
                
</beans> 



以后每次的增量是这一段:

Java代码 复制代码

 

        <bean id="userManager" class="some.package.UserManagerImpl" autoWire="byName"/>



跟配置普通bean的方法一样,非常简洁、直观。对现有的Service接口也无须任何修改

我把Feiing的transactionAttributesSource改成叻transactionAttributes,并且将DefaultAdvisorAutoProxyCreator改成了BeanNameAutoProxyCreator,我觉得毕竟不是context下的每个bean都需要事务,只要在Service层做AOP就可以叻。

和Robbin一致认为,Feiing的做法非常可取,因为它分离了XML配置文件关注点

 

以下是spring+iBatis的配置

作为开源的Orm对象映射框架,ibatis是一个线程安全,学习容易,但是开发相对于hibernate来说的话,就要繁锁些,没有很好的工具支持ibatis所有的配置几乎是通过手写,这样增加了开发者的难度、、好啦,言归正转。下面编写实现。

一、引入spring,ibatis jar包.

二、编写log4j.properties日志文件

      log4j.rootLogger=DEBUG,stdout

      log4j.appender.stdout=org.apache.log4j.ConsoleAppender
      log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
      log4j.appender.stdout.layout.ConversionPattern=%c{1}% - %m%n

      log4j.logger.java.sql.PreparedStatement=DEBUG

      

 

 

三、建立Student.java类映象属性

package org.terry.ibatis.pojo;

public class Student {
 private Long id;

 private String name;

 private String subject;

 private Long score;

 public Long getId() {
  return id;
 }

 public void setId(Long id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public Long getScore() {
  return score;
 }

 public void setScore(Long score) {
  this.score = score;
 }

 public String getSubject() {
  return subject;
 }

 public void setSubject(String subject) {
  this.subject = subject;
 }
}

 

 

 

四、编写 student.xml 映象文件

<?xml version="1.0" encoding="utf-8" ?>

<!DOCTYPE sqlMap      
    PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"      
    "http://ibatis.apache.org/dtd/sql-map-2.dtd">
    
<sqlMap namespace="student">
 <typeAlias alias="student" type="org.terry.ibatis.pojo.Student"/>
 <resultMap class="student" id="studentResult">
  <result property="id" column="id" jdbcType="number" javaType="java.lang.Long"/>
  <result property="name" column="name"/>
  <result property="subject" column="subject"/>
  <result property="score" column="score"/>
 </resultMap>
 
 <select id="selectAll" resultMap="studentResult">
  select * from student
 </select>
 
 <select id="findbyId" parameterClass="java.lang.Long" resultClass="student">
  select * from student where id=#id#
 </select>
 <insert id="insert" parameterClass="student">
  insert into student(id,name,subject,score) values(#id#,#name#,#subject#,#score#)
 </insert>
 <update id="update" parameterClass="student">
  update student set name=#name#,subject=#subject#,score=#score# where id=#id#
 </update>
 <delete id="delete" parameterClass="java.lang.Long">
  delete from student where id=#id#
 </delete>
</sqlMap>

 

 

五、编写 SqlMapConfig.xml文件

<?xml version="1.0" encoding="utf-8" ?>

<!DOCTYPE sqlMapConfig      
    PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"      
    "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
    
<sqlMapConfig>
 <sqlMap resource="org/terry/ibatis/pojo/student.xml"/>
</sqlMapConfig>

 

 

六、编写 StudentDao.java(实现类)

package org.terry.ibatis.dao;

import java.io.IOException;
import java.sql.SQLException;
import java.util.List;

import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.orm.ibatis.SqlMapClientCallback;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
import org.terry.ibatis.pojo.Student;

import com.ibatis.sqlmap.client.SqlMapExecutor;

public class StudentDao extends SqlMapClientDaoSupport implements Idao{

 public void delete(Long id) {
  this.getSqlMapClientTemplate().delete("delete", id);
 }

 public Object findbyId(Long id) {
  return this.getSqlMapClientTemplate().queryForObject("findbyId", id);
 }

 public List getAll() {
  return (List)this.getSqlMapClientTemplate().execute(new SqlMapClientCallback(){

   public Object doInSqlMapClient(SqlMapExecutor sqlMapper) throws SQLException {
    return sqlMapper.queryForList("selectAll");
   }
   
  });
 }

 public void save(Object o) {
  this.getSqlMapClientTemplate().insert("insert", o);
 }

 public void update(Object o) {
  this.getSqlMapClientTemplate().update("update", o);
 }
 
 public static void main(String[] args) throws IOException {
   Resource re=new ClassPathResource("Ibatis-Context.xml");
   XmlBeanFactory xml=new XmlBeanFactory(re);
   StudentDao student=(StudentDao)xml.getBean("studentDao");
   Student stu=new Student();
   stu.setId(Long.valueOf(16));
   stu.setName("terry");
   stu.setScore(Long.valueOf(99));
   stu.setSubject("数学");
   student.delete(Long.valueOf(16));
 }
}

 

 

七、配置 ApplicationContext.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
 <bean id="dataSource"
  class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName">
   <value>oracle.jdbc.driver.OracleDriver</value>
  </property>
  <property name="url">
   <value>jdbc:oracle:thin:@localhost:1521:orcl</value>
  </property>
  <property name="username">
   <value>terry</value>
  </property>
  <property name="password">
   <value>terry</value>
  </property>
 </bean>
 
 <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
  <property name="configLocation" value="SqlMapConfig.xml"/>
  <property name="dataSource" ref="dataSource"></property>
 </bean>
 
 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource"></property>
 </bean>
  <!-- 配置事务拦截器 -->
   <bean id="transactionIterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
    <!-- 事务拦截器需要注入一个事务管理器 -->
    <property name="transactionManager" ref="transactionManager"></property>
    <property name="transactionAttributes">
     <props>
      <prop key="insert*">PROPAGATION_REQUIRED</prop>
      <prop key="find*,get*">PROPAGATION_REQUIRED,readOnly</prop>
      <prop key="*">PROPAGATION_REQUIRED</prop>
     </props>
    </property>
   </bean>
   
   <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
    <property name="beanNames">
     <list>
      <value>*Dao</value>
     </list>
    </property>
    <property name="interceptorNames">
     <list>
      <value>transactionIterceptor</value>
     </list>
    </property>
   </bean>
 <bean id="studentDao" class="org.terry.ibatis.dao.StudentDao">
  <property name="sqlMapClient" ref="sqlMapClient"></property>
 </bean>
</beans>

 

 

这样Ibatis 集成 Spring就实现啦

分享到:
评论
1 楼 geek87 2010-01-30  
很好,,不错

相关推荐

    SpringBoot简化Spring应用初始搭建以及开发过程

    Spring Boot专注于Spring平台和第三方开发库,简化了基于Spring的产品开发。让你在开始Spring应用开发时,不会被各种繁杂的事务困扰。通过Spring Boot,开发时只需少量的Spring配置就可以完成项目结构的初始搭建。

    spring4示例代码

    spring-1 演示了使用setter方式及构造器方式创建bean,util:list标签创建集合,p标签简化配置 和依赖注入, 以及bean的autowire和继承与依赖,以及bean的作用域。 spring-2 演示了外部配置文件的引入(connection)...

    spring课堂笔记的相关知识

    只需要通过配置就可以完成对事务的管理,而无需手动编程 方便程序的测试 Spring对Junit4支持,可以通过注解方便的测试Spring程序 方便集成各种优秀框架 Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀...

    用于将所有Spring xml配置转换为基于Spring java的配置的工具(高分毕设).zip

    Java SSM项目是一种使用Java语言和SSM框架(Spring + Spring MVC + ...它提供了一种将数据库操作与Java对象映射起来的方式,避免了手动编写繁琐的SQL语句,并提供了事务管理和缓存等功能,简化了数据库访问的过程

    Spring-Reference_zh_CN(Spring中文参考手册)

    2.4.1. 在XML里更为简单的声明性事务配置 2.4.2. JPA 2.4.3. 异步的JMS 2.4.4. JDBC 2.5. Web层 2.5.1. Spring MVC的表单标签库 2.5.2. Spring MVC合理的默认值 2.5.3. Portlet 框架 2.6. 其他特性 2.6.1. 动态语言...

    Spring 2.0 开发参考手册

    2.4.1. 在XML里更为简单的声明性事务配置 2.4.2. JPA 2.4.3. 异步的JMS 2.4.4. JDBC 2.5. Web层 2.5.1. Spring MVC的表单标签库 2.5.2. Spring MVC合理的默认值 2.5.3. Portlet 框架 2.6. 其他特性 2.6.1. ...

    spring4.3.2参考文档(英文)

    Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。 Spring AOP:通过配置管理特性,Spring AOP 模块...

    spring4.3.9相关jar包

    spring-beans.jar(必须):这 个jar 文件是所有应用都要用到的,它包含访问配置文件、创建和管理bean 以及进行Inversion of Control / Dependency Injection(IoC/DI)操作相关的所有类。如果应用只需基本的IoC/DI ...

    Spring中文帮助文档

    2.4.1. 在XML里更为简单的声明性事务配置 2.4.2. 对Websphere 事务管理的完整支持 2.4.3. JPA 2.4.4. 异步的JMS 2.4.5. JDBC 2.5. Web层 2.5.1. Spring MVC合理的默认值 2.5.2. Portlet 框架 2.5.3. 基于...

    Spring API

    2.4.1. 在XML里更为简单的声明性事务配置 2.4.2. 对Websphere 事务管理的完整支持 2.4.3. JPA 2.4.4. 异步的JMS 2.4.5. JDBC 2.5. Web层 2.5.1. Spring MVC合理的默认值 2.5.2. Portlet 框架 2.5.3. 基于...

    spring chm文档

    2.4.1. 在XML里更为简单的声明性事务配置 2.4.2. JPA 2.4.3. 异步的JMS 2.4.4. JDBC 2.5. Web层 2.5.1. Spring MVC的表单标签库 2.5.2. Spring MVC合理的默认值 2.5.3. Portlet 框架 2.6. 其他特性 2.6.1. ...

    第24次课-1 Spring与Hibernate的整合

    方便的事务管理:Spring提供的声明式事务处理可以全面有效地处理事务。 异常包装:Spring能够包装Hibernate的异常,使开发者可以选择恰当的层来处理异常。 24.2 管理SessionFactory Hibernate的SessionFactory,是...

    纯spring多库

    纯spring多数据库事务,是spring和atomikos组合使用。有spring注解设置数据源,由atomikos负责数据源管理,负责事务管理。追求零配置。大大简化工作量。供参考

    Spring.3.x企业应用开发实战(完整版).part2

    4.4.7 简化配置方式 4.4.8 自动装配 4.5 方法注入 4.5.1 lookup方法注入 4.5.2 方法替换 4.6 之间的关系 4.6.1 继承 4.6.2 依赖 4.6.3 引用 4.7 整合多个配置文件 4.8 Bean作用域 4.8.1 singleton作用域 4.8.2 ...

    Spring攻略(第二版 中文高清版).part1

    2.8 用Java Config简化XML配置 77 2.8.1 问题 77 2.8.2 解决方案 77 2.8.3 工作原理 77 2.9 使Bean感知容器 81 2.9.1 问题 81 2.9.2 解决方案 81 2.9.3 工作原理 82 2.10 加载外部资源 82 2.10.1...

    spring的概要介绍与分析

    Spring是一个开源的Java应用框架,它旨在简化...Spring Boot是Spring框架的一个子项目,它提供了自动配置、简化依赖管理和内置Web服务器等功能,使得开发者能够更快地构建和部署Spring应用程序。Spring Cloud则是一系列

    spring boot 全面的样例代码

    - chapter3-2-2:[使用Spring-data-jpa简化数据访问层(推荐)](http://blog.didispace.com/springbootdata2/) - chapter3-2-3:[多数据源配置(一):JdbcTemplate]...

    Spring in Action中文版 清晰pdf part2

    附录A介绍如何开始自己的Spring应用系统,如何下载Spring以及如何编写Ant配置文件。附录B介绍一些与Spring有关的其他开源框架。本书的每一部分既是建立在前一部分的基础上,同时也都是独立存在的,所以,读者不必...

    Spring面试71题与答案

     事务管理:Spring提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。  异常处理:Spring提供方便的API把具体技术相关的异常(比如由JDBC,HibernateorJDO抛出的)转化为一致的...

    SpringCloud Alibaba 实战2021年

    │ 12 配置中心:基于 Naco 集中管理应用配置.mp4 │ 15 应用性能监控:通过 SkyWalking 实施链路追踪.mp4 │ 16 分布式事务:Alibaba Seata 如何实现分布式事务.mp4 │ 17 消息队列:基于 RocketMQ 实现服务...

Global site tag (gtag.js) - Google Analytics