Spring注解和XML配置的区别?为什么事务用XML配置更好?

一、annotation和XML的优缺点

Spring的annotation注入机制与XML注入机制本质上是相同的。annnotation简洁一些,遵循一些IOC。

XML配置的优缺点:
优点有:
1. XML配置方式进一步降低了耦合,使得应用更加容易扩展,即使对配置文件进一步修改也不需要工程进行修改和重新编译。
2. 在处理大的业务量的时候,用XML配置应该更加好一些。因为XML更加清晰的表明了各个对象之间的关系,各个业务类之间的调用。同时spring的相关配置也能一目了然。
当然,有人会说,用XML配置,在大的业务量时候会使得XML文件过大,不容易查看。这一点我们完全可以利用业务分解书写多个XML配置文件就可以了。

缺点有:
配置文件读取和解析需要花费一定的时间,配置文件过多的时候难以管理,无法对配置的正确性进行校验,增加了测试难度。


annotation配置的优缺点:
优点有:
1. 在class文件中,可以降低维护成本,annotation的配置机制很明显简单
2. 不需要第三方的解析工具,利用java反射技术就可以完成任务
3. 编辑期可以验证正确性,差错变得容易
4. 提高开发效率

缺点有:
1. 如果需要对于annotation进行修改,那么要重新编译整个工程
2. 业务类之间的关系不如XML配置那样容易把握。
3. 如果在程序中annotation比较多,直接影响代码质量,对于代码的简洁度有一定的影响。

有些人喜欢annotation, 这样bean的声明,注册,注入都在“刚好”的地方出现,很自然。

个人觉得xml比较好用,整体业务关系清晰,易维护。

 

二、Spring事务用xml配置

注释配置往往是类级别的,而xml配置则可以表现的更加灵活。是用 aop/tx 命名空间的配置更加灵活简单。

 

Propagation :key属性确定代理应该给哪个方法增加事务行为。这样的属性最重要的部份是传播行为。有以下选项可供使用:

PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED--Nested的事务和他的父事务是相依的,他的提交是要等和他的父事务一块提交的。

 

<?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:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <import resource="applicationContext.xml"/>
    <!-- Spring myBatis3模板配置 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:/myBatis.xml" />
        <!--<property name="typeAliasesPackage" value="org.snaker.engine.entity" />-->
        <property name="mapperLocations">
            <list>
                <value>
                    classpath*:com/hide168/library/*/dao/*.xml
                </value>
                <value>
                    classpath*:com/hide168/module/*/dao/*.xml
                </value>
                <value>
                    classpath*:com/hide168/protal/*/dao/*.xml
                </value>
                <value>
                    classpath*:com/hide168/protal/*/*/dao/*.xml
                </value>
            </list>
        </property>
    </bean>
    <!-- mybatis spring sqlSessionTemplate -->
    <bean id="myBatisSqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory"></constructor-arg>
    </bean>

    <!-- mybatis mapper, 接口形式的访问 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.ztesoft.resmaster.module.dat.mapper"></property>
        <!--<property name="sqlSessionFactory" ref="myBatisSessionFactory"></property>-->
        <!--上面这句会导致:org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class '${jdbc.driver}'-->
        <property name="sqlSessionFactoryBeanName" value="myBatisSessionFactory"></property>
    </bean>

    <!-- 局部事务管理器,本地开发使用 -->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
        <property name="globalRollbackOnParticipationFailure" value="false" />
    </bean>
    <!--<tx:annotation-driven transaction-manager="myBatisTransactionManager" />-->

    <!-- proxy-target-class true:CGLIB代理 false:JDK代理-->
    <aop:aspectj-autoproxy proxy-target-class="true" />

    <tx:advice id="myBatisTxAdvice" transaction-manager="transactionManager">
        <tx:attributes>
	    <!-- propagation设定事务传播级别-->
            <tx:method name="delete*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception"/>
            <tx:method name="insert*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception"/>
            <tx:method name="update*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception"/>
            <tx:method name="save*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception"/>
            <tx:method name="add*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception"/>
            <tx:method name="*" read-only="true" propagation="NOT_SUPPORTED" />
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <aop:advisor advice-ref="myBatisTxAdvice" pointcut="
             execution(* com.hide168.module.*.service..*.*(..))
		  or execution(* com.hide168.mobile.*.service..*.*(..))
		  or execution(* com.hide168.protal.*.*.service..*.*(..))"
        />
    </aop:config>

    <!--<aop:aspectj-autoproxy proxy-target-class="true" />-->

    <!-- 用于支持上传文件 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>

</beans>

   这是使用注解方式时要配置的,代码中的具体的注解以及事务的传播性、隔离级别一般在service 层中配置

 

 

annotation方式配置事务: 

@Transactional

(1)、这里说明一下,有的把这个注解放在类名称上面了,这样你配置的这个@Transactional 对这个类中的所有public方法都起作用

(2)、@Transactional 方法方法名上,只对这个方法有作用,同样必须是public的方法

比如这里就对这个方法定义了一个事务同时设置了很多属性:

@Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class,timeout=1,isolation=Isolation.DEFAULT)  
public void saveUser(Map<String, String> map) throws Exception {  
        System.out.println("方法开始");  
    for (int i = 0; i < 500000; i++) {  
            System.out.println("*");  
        }  
     System.out.println("进入保存");  
     userDao.saveUser(map);  
     System.out.println("退出保存");  
}  

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值