Spring事务管理 ——》java service

java的事务处理,如果对数据库进行多次操作,每一次的执行或步骤都是一个事务.如果数据库操作在某一步没有执行或出现异常而导致事务失败,这样有的事务被执行有的就没有被执行,从而就有了事务的回滚,取消先前的操作.....

注:在Java中使用事务处理,首先要求数据库支持事务。如使用MySQL的事务功能,就要求MySQL的表类型为Innodb才支持事务。否则,在Java程序中做了commit或rollback,但在数据库中根本不能生效。

1.JavaBean中使用JDBC方式进行事务处理

public int delete(int sID) { 
  dbc = new DataBaseConnection(); 
  Connection con = dbc.getConnection(); 
  try { 
   con.setAutoCommit(false);// 更改JDBC事务的默认提交方式 
   dbc.executeUpdate("delete from xiao where ID=" + sID); 
   dbc.executeUpdate("delete from xiao_content where ID=" + sID); 
   dbc.executeUpdate("delete from xiao_affix where bylawid=" + sID); 
   con.commit();//提交JDBC事务 
   con.setAutoCommit(true);// 恢复JDBC事务的默认提交方式 
   dbc.close(); 
   return 1; 
  } 
  catch (Exception exc) { 
   con.rollBack();//回滚JDBC事务 
   exc.printStackTrace(); 
   dbc.close(); 
   return -1; 
  } 
}

在数据库操作中,一项事务是指由一条或多条对数据库更新的sql语句所组成的一个不可分割的工作单元。只有当事务中的所有操作都正常完成了,整个事务才能被提交到数据库,如果有一项操作没有完成,就必须撤消整个事务。

************************************接触过公司框架spring事务**************************************

<!-- 事务管理器 -->
 <bean id="transactionManager"
  class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory" />
 </bean>

<!-- 事务拦截器 -->
 <bean id="transactionInterceptor"
  class="org.springframework.transaction.interceptor.TransactionInterceptor">
  <!-- 事务管理器 -->
  <property name="transactionManager" ref="transactionManager" />
  <property name="transactionAttributes">
   <props>
    <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
    <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
    <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
    <prop key="check*">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="create*">
     PROPAGATION_REQUIRED
    </prop>
    <prop key="del*">
     PROPAGATION_REQUIRED
    </prop>
    <prop key="update*">
     PROPAGATION_REQUIRED
    </prop>
    <prop key="start*">
     PROPAGATION_REQUIRED
    </prop>
    <prop key="cancel*">
     PROPAGATION_REQUIRED
    </prop>
    <prop key="stop*">
     PROPAGATION_REQUIRED
    </prop>
    <prop key="save*">
     PROPAGATION_REQUIRED
    </prop>
    <prop key="add*">
     PROPAGATION_REQUIRED
    </prop>
    <prop key="remove*">
     PROPAGATION_REQUIRED
    </prop>
    <prop key="pay*">
     PROPAGATION_REQUIRED
    </prop>

<prop key="*">PROPAGATION_REQUIRED</prop>

</props>
  </property>
 </bean>

<!-- 定义所有的BPO自动添加事务拦截器 -->
 <bean
  class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
  <property name="beanNames">
   <list>
    <value>*BPO</value>
   </list>
  </property>
  <property name="interceptorNames">
   <!-- 事务拦截器 -->
   <list>
    <value>monitorInterceptor</value>
    <!-- 异常处理拦截器,异常处理拦截器要在事务拦截器之后,因为可以会有数据库错误等事务相关的异常 -->
    <value>exceptionInterceptor</value>
    <!--  缓存拦截器,一般拦截BPO的更新,删除,BO的查找方法 -->
    <value>cacheInterceptor</value>

<value>transactionInterceptor</value>
    <!-- 版本记录拦截器 要在事务拦截器内进行拦截 -->
    <!--
    <value>versionInterceptor</value>
    -->
    <!-- 业务日志拦截器,必须放在事务拦截器下的.否则不在同一事务中 -->
    <value>businessLogInterceptor</value>
   </list>
  </property>
 </bean>

*****************************************spring 详解******************************************************************

出自:http://www.cnblogs.com/rushoooooo/archive/2011/08/28/2155960.html

附一、Spring事务类型详解

<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop><prop key="store*">PROPAGATION_REQUIRED</prop>

估计有好多朋友还没有弄清楚里面的值的意思,仔细看完下面应该知道自己什么情况下面应该使用什么样的声明。^_^

Spring中常用事务类型:

PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。

PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。

附二、对spring事务类型详解的一点补充(关于嵌套事务)

· PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。

· PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。

· PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。

· PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。

· PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

· PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。

可能大家对PROPAGATION_NESTED还不怎么了解,觉得有必要再补充一下^_^!
PROPAGATION_NESTED: 嵌套事务类型,是相对上面提到的六种情况(上面的六种应该称为平面事务类型),打个比方我现在有一个事务主要有一下几部分:
      1,从A用户帐户里面减去100元钱
      2,往B用户帐户里面添加100元钱
       这样看和以前不同的事务可能没有什么区别,那我现在有点特殊的要求就是,A用户有3个帐户,B用户有2个帐户,现在我的要求就是只要再A用户的3个帐户里面任意一个减去100元,往B用户的两个帐户中任意一个里面增加100元就可以了!
       一旦你有这样的要求那嵌套事务类型就非常适合你!我们可以这样理解,
       一:将“从A用户帐户里面减去100元钱” 和 “往B用户帐户里面增加100元钱”我们暂时认为是一级事务操作
       二:将从A用户的3个帐户的任意一个帐户里面减钱看做是“从A用户帐户里面减去100元钱”这个一级事务的子事务(二级事务),同样把后面存钱的看成是另一个的二级事务。
      问题一:当二级事务被rollback一级事务会不会被rollback?
      答案是不会的,二级事务的rollback只针对自己。
      问题二:什么时候这个一级事务会commit,什么时候会被rollback呢?
      我们主要看二级里面出现的情况,当所有的二级事务被commit了并且一级事务没有失败的操作,那整个事务就算是一个成功的事务,这种情况整个事务会被commit。
当任意一个二级事务没有被commit那整个事务就是失败的,整个事务会被roolback。
还是拿上面的例子来说明吧!如果我在a的三个帐户里面减钱的操作都被二级事务给rollback了,也就是3个帐户里面都没有减钱成功,整个事务就失败了就会被rollback。如果A用户帐户三个帐户里面有一个可以扣钱而且B用户的两个帐户里面也有一个帐户可以增加钱,那整个事务就算成功的,会被 commit。
看了一下觉得上面的例子好像不是很深刻,看这个情况(A用户的3个帐户都是有信用额度的,也就是说可以超支,但是超支有金额限制)。不过原理是一样的,简单点也好说明一点,祝你好运!^_^

附三、Transaction后缀给声明式事务管理带来的好处

良好的面向对象的程序,一般都使用接口和实现分离的模式。我在《事务管理最佳实践全面解析》一文中提出,用*Transaction和*Dao后缀这样的形式,区分方法的不同用途。

这样,可以提醒接口的实现者和方法的使用者注意到它们对于数据库连接和事务的依赖。

实际上,使用*Transaction后缀这样的命名方式,对于声明式事务管理也是很有用处的。如,Spring的事务管理中,我们一般使用方法名的匹配来应用声明式事务。

一、请看下面的Spring配置:

<bean id="txProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

<property name="transactionManager" ref="transactionManager"/>

<property name="transactionAttributes">

<props>

    <prop key="*">readOnly</prop>

    <prop key="add*">PROPAGATION_REQUIRED,-Exception</prop>

    <prop key="save*">PROPAGATION_REQUIRED,-Exception</prop>

    <prop key="modify*">PROPAGATION_REQUIRED,-Exception</prop>

    <prop key="update*">PROPAGATION_REQUIRED,-Exception</prop>

    <prop key="delete*">PROPAGATION_REQUIRED,-Exception</prop>

    <prop key="remove*">PROPAGATION_REQUIRED,-Exception</prop>

    <prop key="query*">PROPAGATION_REQUIRED, readOnly,-Exception</prop>

    <prop key="load*">PROPAGATION_REQUIRED, -Exception</prop>

</props>

</property>

</bean>

这是来自于真实项目中的Spring声明式事务配置。我们对每一个业务层的实现类都应用了这样的事务配置。

我们对所有业务服务Service方法使用了只读事务。对以add,save,modify,update,delete,remove,load开头的方法都使用了事务。

但是,实际上,虽然我们开发的软件一个“信息管理系统”,是围绕数据库开发的。但是,在Service层,我们还是有很多不操作数据库的方法。

如,单纯根据业务逻辑进行计算的,适用缓存进行计算的,执行email发送,文件上传等等任务的方法,在这种配置下都不分青红皂白的应用了事务。

SpringAOP生成的代理对象代理了我们的服务实现类,所有的方法执行前后都被拦截,用来得到和关闭数据库连接,设置、提交和回滚事务。而不管这个方法是否用到了这个数据库。

如果遵照我提出的这个方法,使用*Transaction后缀来标识需要处理事务的方法,那么我们使用Spring声明式事务时,就可以非常精确、有效的应用事务了!

二、请看下面的Spring事务配置:

<!-- UninstallWcmsJbpmProcessDefinition -->

<bean id="uninstallWcmsJbpmProcessDefinition" parent="txProxyTemplate">

    <property name="target">

       <ref bean="uninstallWcmsJbpmProcessDefinitionTarget"/>

    </property>

<property name="transactionAttributes">

<props>

      <prop key="uninstall*Wcms*Transaction">PROPAGATION_REQUIRED,-Exception</prop>

</props>

</property>

</bean>

我们对这个类中以uninstall开头,中间包含Wcms,最后以Transaction结尾,这样的规则命名的方法,应用了事务。

三、部分源代码:

(一)2个应用了Spring声明式事务的方法:

?

/** 

*使用SPring的ibatis,主要要配置iBatis的Spring声明式事务。 

*@throwsException 

*<prop key="uninstall*Wcms*Transaction">PROPAGATION_REQUIRED,-Exception</prop> 

*1,还要删除所有 频道---新闻--工作流表中标记不为1的记录。 

*/

publicvoid uninstallAllWcmsProcessDefinitionsTransaction() throws Exception{ 

/** 

*/

this.getWcmsSystemChannelProcessdefinitionDao().deleteAll(); 

this.getWcmsSystemChannelNewsinfoDao().deleteAllProcessingWcmsSystemChannelNewsinfoModule(); 

    

/** 

*<prop key="uninstall*Wcms*Transaction">PROPAGATION_REQUIRED,-Exception</prop> 

*@paramname 

*@throwsException 

*/

publicvoid uninstallWcmsSystemChannelProcessdefinitionTransaction(String name) throws Exception{ 

this.getWcmsSystemChannelProcessdefinitionDao().deleteByProcessdefinitionName(name); 

this.getWcmsSystemChannelNewsinfoDao().deleteAllProcessingWcmsSystemChannelNewsinfoModuleByProcessdefinitionName(name); 

    

(二)用到的Dao类,用来实际访问数据库的2个DAO对象。

 

/**

 

*SPring管理的ibatis功能

 

*/

 

private IWcmsSystemChannelProcessdefinitionDao wcmsSystemChannelProcessdefinitionDao;

 

private IWcmsSystemChannelNewsinfoDao wcmsSystemChannelNewsinfoDao;

附四、Spring中的四种声明式事务的配置

让我们言归正传吧。

以下两个bean的配置是下面要用到的。

<!-- 定义事务管理器(声明式的事务) -->
<bean id="transactionManager"
   class="org.springframework.orm.hibernate3.HibernateTransactionManager">
   <property name="sessionFactory">
    <ref local="sessionFactory" />
   </property>
</bean>

<!-- *******业务逻辑层(是对各个DAO层的正面封装)主要用到<<门面模式>>****** -->
<bean id="fundService"
   class="com.jack.fund.service.serviceimpl.FundService">
   <property name="operdao">
    <ref bean="operatorDAO" />
   </property>
   <property name="producedao">
    <ref bean="fundProduceDAO" />
   </property>
   <property name="customerdao">
    <ref bean="customerDAO" />
   </property>
   <property name="accountdao">
    <ref bean="accountDAO" />
   </property>
   <property name="fundaccountdao">
    <ref bean="fundAccountDAO" />
   </property>
   <property name="fundtransdao">
    <ref bean="fundTransDAO" />
   </property>
</bean>

可能还有其他很多模块。<bean id="fundService"/>可能只是其中的模块。

第一种:配置声明式事务的方法如下。也是我们最常用的方法了,它适用于你的库表比较少的情况下。

<bean id="fundServiceDAOProxy"
   class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
   <!-- 配置事务管理器 -->
   <property name="transactionManager">
    <ref bean="transactionManager" />
   </property>
   <!-- 此属性指定目标类本省是否是代理的对象,如果目标类没有实现任何类,就设为true代表自己 -->
   <property name="proxyTargetClass">
    <value>false</value>
   </property>
   <property name="proxyInterfaces">
    <value>com.jack.fund.service.IFundService</value>
   </property>
   <!-- 目标bean -->
   <property name="target">
    <ref bean="fundService" />
   </property>
   <!-- 配置事务属性 -->
   <property name="transactionAttributes">
    <props>
     <prop key="delete*">PROPAGATION_REQUIRED</prop>
     <prop key="add*">PROPAGATION_REQUIRED</prop>
     <prop key="update*">PROPAGATION_REQUIRED</prop>
     <prop key="save*">PROPAGATION_REQUIRED</prop>
     <prop   key="find*">PROPAGATION_REQUIRED,readOnly</prop>
    </props>
   </property>
</bean> 以下可能还有其他的xxxServiceDAOProxy.大家可以看出针对每一个功能模块配置一个业务代理服务。如果模块多大话,就显得代码有点多了,发现他们只是稍微一点不一样。这时我们就应该想到继承的思想。用第二种方法。第二种:配置声明式事务的方法如下。这种情况适合相对比较多的模块时使用。
<!-- 利用继承的思想简化配置,要把abstract="true" -->
<bean id="transactionBase"
   class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
  lazy-init="true" abstract="true">
   <!-- 配置事务管理器 -->
  <property name="transactionManager">
    <ref bean="transactionManager" />
  </property>
   <!-- 配置事务属性 -->
  <property name="transactionAttributes">
    <props>
    <prop key="delete*">PROPAGATION_REQUIRED</prop>
     <prop key="add*">PROPAGATION_REQUIRED</prop>
    <prop key="update*">PROPAGATION_REQUIRED</prop>
     <prop key="save*">PROPAGATION_REQUIRED</prop>
    <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
    </props>
   </property>
</bean> 而具体的模块可以简单的这样配置。只要指明它的parent(父类)就可以了。父类一般把abstract="true",因为在容器加载的时候不需要初始化,等到用的时候再有它的子类调用的时候,再去初始化。
<bean id="fundServiceDAOProxy" parent="transactionBase" >
   <property name="target">
   <ref bean="fundService" />
  </property>
</bean> 

  这样配置的话,如有多个像fundService这样模块时,可以少些很多重复的代码。第三种:配置声明式事务的方法如下。主要利用BeanNameAutoProxyCreator自动创建事务代理<bean id="transactionInterceptor"

   class="org.springframework.transaction.interceptor.TransactionInterceptor">

  <property name="transactionManager">
    <ref bean="transactionManager" />
   </property>
   <!-- 配置事务属性 -->
   <property name="transactionAttributes">
   <props>
     <prop key="delete*">PROPAGATION_REQUIRED</prop>
    <prop key="add*">PROPAGATION_REQUIRED</prop>
     <prop key="update*">PROPAGATION_REQUIRED</prop>
    <prop key="save*">PROPAGATION_REQUIRED</prop>
     <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
   </props>
   </property>
</bean>
<bean
   class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
   <property name="beanNames">
   <list>
     <value>fundService</value>
   </list>
   </property>
   <property name="interceptorNames">
    <list>
     <value>transactionInterceptor</value>
    </list>
  </property>
</bean>

这种方法主要利用了拦截器的原理。前三种方法一般都必需指定具体的模块bean.如果模块过多话,比如一个大型的网站一般有几十个模块。我们就得考虑用第四种的配置方式了。自动创建事务代理的方式了。第四种:配置声明式事务的方法如下。

<bean id="transactionInterceptor"
   class="org.springframework.transaction.interceptor.TransactionInterceptor">

   <property name="transactionManager">
    <ref bean="transactionManager" />
   </property>
<!-- 自动代理 -->
<bean id="autoproxy"
   class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
   <!-- 可以是Service或DAO层(最好是针对业务层*Service) -->
   <property name="beanNames">
    <list>
    <value>*Service</value>
    </list>
   </property>
   <property name="interceptorNames">
    <list>
        <value>transactionInterceptor</value>
    </list>
   </property>
</bean>

自动代理还有一种用法就是结合正规表达式和advice使用。<bean id="transactionInterceptor"

   class="org.springframework.transaction.interceptor.TransactionInterceptor">

   <property name="transactionManager">
   <ref bean="transactionManager" />
   </property>

<bean id="autoProxyCreator"
   class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
<bean id="regexpMethodPointcutAdvisor"
   class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
   <property name="advice">
   <ref bean="transactionInterceptor" />
   </property>
   <property name="pattern">
   <value>.*</value>
   </property>
   </bean>

Spring事务管理 ——》java service

时间: 2024-10-04 19:25:16

Spring事务管理 ——》java service的相关文章

Spring事务管理(详解+实例)

写这篇博客之前我首先读了<Spring in action>,之后在网上看了一些关于Spring事务管理的文章,感觉都没有讲全,这里就将书上的和网上关于事务的知识总结一下,参考的文章如下: Spring事务机制详解 Spring事务配置的五种方式 Spring中的事务管理实例详解 1 初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱. 比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱:然后ATM出1000元钱.这两个步骤必须是要么都执行要么都

Spring事务管理

写这篇博客之前我首先读了<spring in action>,之后在网上看了一些关于Spring事务管理的文章,感觉都没有讲全,这里就将书上的和网上关于事务的知识总结一下,参考的文章如下: Spring事务机制详解 Spring事务配置的五种方式 Spring中的事务管理实例详解 1 初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱. 比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱:然后ATM出1000元钱.这两个步骤必须是要么都执行要么都

Spring 事务管理高级应用难点剖析--转

第 1 部分 http://www.ibm.com/search/csass/search/?q=%E4%BA%8B%E5%8A%A1&sn=dw&lang=zh&cc=CN&en=utf&hpp=20&dws=cndw&lo=zh 概述 Spring 最成功,最吸引人的地方莫过于轻量级的声明式事务管理,仅此一点,它就宣告了重量级 EJB 容器的覆灭.Spring 声明式事务管理将开发者从繁复的事务管理代码中解脱出来,专注于业务逻辑的开发上,这是一件

spring事务管理——编程式事务、声明式事务

本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本教程假定您已经掌握了 Java 基础知识,并对 Spring 有一定了解.您还需要具备基本的事务管理的知识,比如:事务的定义,隔离级别的概念,等等.本文将直接使用这些概念而不做详细解释.另外,您最好掌握数据库的基础知识,虽然这不是必须. 系统需求 要试验这份教程中的工具和示例,硬件配置需求为:至少带有 512MB 内存(

[Spring框架]Spring 事务管理基础入门总结.

前言:在之前的博客中已经说过了数据库的事务, 不过那里面更多的是说明事务的一些锁机制, 今天来说一下Spring管理事务的一些基础知识. 之前的文章: [数据库事务与锁]详解一: 彻底理解数据库事务一, 什么是事务 事务是逻辑上一组操作,这组操作要么全都成功,要么全都失败. 事务的属性: ACID原子性(Atomicity): 事务作为一个整体被执行,包含在其中的对数据的操作要么全部被执行,要么都不执行.一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态.

spring事务管理及相关知识

最近在项目中遇到了spring事务的注解及相关知识,突然间感觉自己对于这部分知识只停留在表面的理解层次上,于是乎花些时间上网搜索了一些文章,以及对于源码的解读,整理如下: 一.既然谈到事务,那就先搞清到底什么是事务,或者说,Spring事务管理中的事务到底是指什么? 1.事务(Transaction),通常是指数据库的事务,在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit),例如insert .update.delete等,事务是恢复和并发控制的基本单位. 2.事务

spring 事务管理配置

一般的,我们把事务配在service层,利用service的业务逻辑接口统一的管理. 为什么不用在dao层呢? 因为一个service有可能调用多个dao,而这多个dao有可能相互联系,有时候一个操作需要调用多次数据库,但是这多次调用要么全提交,要么全回滚. 因此,在dao层调用事务理论上说不是一个很明智的选择.应该有业务逻辑层service层负责事务,统一处理. Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三

Spring第三天——JdbcTemplate和spring事务管理

大致内容: aspectJ的aop操作(基于注解,对比day02配置操作)(会用) *jdbcTemplate操作(实现CRUD) *spring配置连接池 *spring事务管理 一.AspectJ的基于注解的AOP操作 (day02的配置回顾,略显麻烦,配置稍多) 建立项目记得导入day02操作aop的那些包(如果是复制项目一定要修改项目的context name) 再把配置文件拿过来 <?xml version="1.0" encoding="UTF-8"

Spring事务管理实现原理及MySQL InnoBD引擎行锁概述

Spring实现事务管理的机制 Spring事务管理是基于AOP编程思想实现,Spring框架被广泛使用的原因之一,就是提供了强大的事务管理机制. AOP是什么?我们常说的AOP并不是指一种开发技术,而是一种编程思想,AOP的核心概念就是面向切面编程,实现可插拔,降低程序之前的耦合性,提高重用性. Spring AOP 基于动态代理实现,一种是JDK动态代理,另一种是CGLIB动态代理. spring2.5之前声明式事务可以这样实现: ?<!-- 声明使用的spring事务管理器--> <