spring

什么是spring

  Spring是分层的javaSE/EE(一站式)轻量级框架

  分层:

Sum提供的EE的三层架构,web层  业务层  数据访问层(持久层)

Struts2是web层基于MVC设计模式的框架

Hibernate是持久的ORM框架

  一站式:【spring对每一层都有自己的解决方案】

Web层:springMVC

持久层:JDBC Template

业务层:spring的Bean管理

 

Spring的核心

Ioc(Inversion of Control) 控制反转

控制反转:将对象的创建权,交给spring完成

Aop(Aspect Oriented Programming) 面向切面编程

 

IOC控制反转的核心

Spring的版本:

  Spring3.x和spring4.x

  Spring3.2是spring3里面最高的版本

  Spring3.0.2里面有依赖包:c3p0,dbcp,log4j,之后的版本就不在提供了

  Spring4.x需要整合hibernate4.x

 

Spring优点:

  方便解耦,简化开发

  Spring是一个大工厂,可以将所有的对象的创建和组建的依赖关系,交给spring来管理

  AOP编程的支持

  Spring提供了面向切面的编程,可以方便的实现程序的增强功能 如:写让日志/权限控制。

  声明式事物的支持

  只需要通过配置就可以完成事务的管理,无须自己手动编写

  方便程序的测试

  Spring对局junit4支持

  方便集成各种优秀的框架

  Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架【h/s/m】的直接支持

  降低了javaEEAPI的使用难度

  Spring对javaEE开发中的API做了包装。

 

 

Spring的入门程序

1.下载spring的开发包

  spring-framework-3.2.0.RELEASE-dist   ----spring的开发包

   *docs    spring框架的API和规范

  *libs     spring 开发的jar包

  *schema  xml的约束文档【dtd】

  spring-framework-3.0.2.RELEASE-dependencies    --spring的开发依赖包

 

2.导入开发常用的基础jar包

  创建java项目引入对应的jar包

  spring-beans-3.2.0.RELEASE.jar

  spring-context-3.2.0.RELEASE.jar

  spring-core-3.2.0.RELEASE.jar

spring-expression-3.2.0.RELEASE.jar

spring-framework-3.0.2.RELEASE-dependencies\org.apache.commons\com.springsource.org.apache.commons.logging\1.1.1\com.springsource.org.apache.commons.logging-1.1.1.jar

spring-framework-3.0.2.RELEASE-dependencies\org.apache.log4j\com.springsource.org.apache.log4j\1.2.15\com.springsource.org.apache.log4j-1.2.15.jar

 

3.创建spring的配置文件

  1.在资源目录下创建一个applicationContext.xml

  2.引入xml的约束【DTD头】

  <beansxmlns="http://www.springframework.org/schema/beans"

      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xsi:schemaLocation="

http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd">

   //我们在这个写东西

</beans>

   3.配置类

如:<beanid="ub" class="biz.UserBiz"></bean>

  

   4.创建测试类

    1.解析配置文件

      ApplicationContext 工厂类  专门解析配置文件的

    2.由spring给我们创建对象

    3.我们得到对象后直接可以访问对象中的方法

 

Ioc和DI的区别?

Ioc:控制反转:将对象的创建权 由spring管理。

DI:依赖注入:在spring创建对象的过程中,把对象依赖的属性注入到类中。

*面向对象中对象之间的关系

   *依赖

      Public class A{

         Public B b;

         b.add();

}

   *继承  is a

   *聚合

      聚集:类和类的关系紧密  如头和身体

      组合:类与类的关系比较松散  如:电视机和遥控器

 

我们必须给创建对象的类中 需要注入值的 属性提供set方法

在bean节点中 添加节点

<propertyname="name" value="刘升东"></property>    对于普通属性的注入

<propertyname="ub" ref="ub"></property>     对于对象属性的注入

Ref=一个bean的id


Spring框架加载配置文件

ApplicationContext 应用上下文 加载spring框架配置文件

加载classPath:

  newClassPathXmlApplicationContext("applicationContext.xml");

  加载classpath下面配置的文件

加载磁盘路径

  newFileSystemXmlApplicationContext("E:\\spring\\spring-day01-1\\property\\applicationContext.xml");

   加载对应磁盘路径下的配置文件

 

BeanFactory与ApplicationContext区别?

ApplicationContext类继承BeanFactory

BeanFactory在使用的时候 用到getBean(“id”)的时候才会加载这个类!

ApplicationContext类加载配置文件的时候会创建所有的配置好的类【bean】

ApplicationContext对BeanFactory提供了扩展

  *事件的传递

  *Bean自动装配

  *各种不同应用层Context的实现

------早期开发使用BeanFactory


Ioc装配Bean

  Spring框架实例化Bean的方式

  提供了三种方式:

  1.构造方法实例化:(最常用的  默认的  使用的是无参构造)

  2.静态工厂实例化

  3.实例化工厂实例化

 

Bean的其他配置

  Id和name的区别

  Id遵守xml的约束,这个约束保证这个属性的值是惟一的。而且必须以字母开头

  可以使用字母,数字,连字符,下划线,句号

  Name没有这一些要求

  …….如果bean标签上没有配置id ,那么name作为id

  …….name是出现在早期开发中的

  …….现在的开发都使用id属性即可

Bean的作用范围

   Scope属性

     *singleton   单例的(默认值)

    *prototype   多例的

    *request  

     Web开发中创建一个对象,将这个对象存入request域中 request.setAttributer()

    *session

     Web开发中创建一个对象,将这个对象存入session域中sesssion.setAttributer()

 

Bean的生命周期

  配置Bean的初始化和销毁的方法

  配置初始化销毁的方法在《bean节点中指定的属性》

  Init-method=”对应的方法名”   //对象创建的时候调用

  Destory-method=”对应的方法名” //关闭工厂的时候销毁  close方法

 

Bean的生命周期的11个步骤:

1.instantiate bean对象实例化   

2.populate properties 封装属性 

3.如果Bean实现BeanNameAware执行 setBeanName   

4.如果Bean实现BeanFactoryAware或者 ApplicationContextAware 设置工厂 setBeanFactory 或者上下文对象setApplicationContext

5.如果存在类实现 BeanPostProcessor(后处理Bean),执行postProcessBeforeInitialization

6.如果Bean实现InitializingBean执行 afterPropertiesSet

7.调用<beaninit-method="init"> 指定初始化方法 init

8.如果存在类实现 BeanPostProcessor(处理Bean),执行postProcessAfterInitialization

9.执行业务处理

10.如果Bean实现DisposableBean 执行 destroy

11.调用<bean destroy-method="customerDestroy">指定销毁方法 customerDestroy

 

Bean属性的注入

   Spring支持setter方法注入/支持构造的注入

   构造器注入:

   <beanid="ua" class="web.action.UserAction" >

      <!--  构造器注入 更具属性名

<constructor-argname="name" value="刘升东" />

      <constructor-arg name="ub" ref="ub2"/>

 -->

  构造器注入  更具形参的下标

      <constructor-arg index="0"type="java.lang.String" value="流水线" />

      <constructor-arg index="1"ref="ub2"></constructor-arg>

</bean>

 

Setter方法的注入:[用的做多的]

   <bean id="ua"class="web.action.UserAction" >

      普通属性的注入

      <property name="name"value="刘升东"></property>

      对象属性的注入 ref  是一个 Bean的id

      <property name="ub"ref="ub2"></property>

    </bean>

 

名称空间P:属性注入

  Spring2.5版本之后引入的

 

  导入P标签的名称空间

  <beans xmlns="http://www.springframework.org/schema/beans"

      xmlns:p="http://www.springframework.org/schema/p"

      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  普通属性的注入

     P:属性名=“lsd” 注入常量

  对象属性的注入

     P:属性名-ref=”id” 注入Bean对象

如:<bean id="ua" class="web.action.UserAction" p:name="刘升东" p:ub-ref="ub2"></bean>

 

分割配置文件;【一旦声明的实例过多了  查找修改起来比较麻烦 找半天找不到】

一种写法:ApplicationContext ac=new ClassPathXmlApplicationContext("acDao.xml","acBz.xml");

第二种写法:

在一个主配置中引入其他的配置

<import resource="applicationContextdao.xml"/>

解析的时候只需要解析主配置就可以了

ApplicationContext ac=newClassPathXmlApplicationContext("applicationContext.xml");

 

IOC装配Bean(注解方式)   不需要提供set方法

   Spring2.5引用了注解去定义Bean

   @Component   用来描述spring框架中的bean

 

   Spring的框架提供了与@Component注解等效的三个注解

   @Repository  用于对dao实现类进行标注

   @Service     用于对service实现类进行标注

   @Controller   用于对Controller 实现类进行标注

-------------三个注解为了后续版本进行增加的!

 

Bean属性的注入

  普通属性

  @Value

 如:@Value("动")

          private String name;

 

  对象属性

  @Autowired

   @Qualifier("ubi2")

   如:@Autowired

       @Qualifier("ubi2")    //ubi2 就是Bean id

            private UserBiz ub=null;

 

@Autowired

@Qualifier("ubi2")

等价于

@Resource(name=”ubi2”)

 

Bean其他属性的配置:

   配置初始化方法/销毁方法

   @PostConstruct  初始化

   @PreDestroy   销毁

 

   配置Bean的作用范围

   @Scope("prototype")   //写在 @Component的下面


实际开发中使用XML还是注解?

   Xml:

    *bean 管理比较方便

   注解:

    *注入属性的时候比较方便

 

两种方式合二为一:

   一般使用xml注册Bean  使用注解来进行属性的注入

AOP的概述

什么是AOP

AOP为Aspect OrientedProgramming的缩写,意为:面向切面编程

AOP采取横向抽取机制,取代了传统的纵向继承体系实现代码的复用

SpringAOP是才有纯java 的是实现,不需要通过专门的编译过程和类加载器。

在运行期通过代理方式向目标对象织入增强

 

AspectJ 是基于java语言的AOP框架,在spring2.0提供了一套专门的编译器。

 

AOP思想


Spring的AOP代理:

   JDK动态代理:对实现了接口的类生成代理   创建快执行慢

   Cglib代理:对类生成的二进制文件的代理    创建慢执行块

 <aop:configproxy-target-class="false"> false默认的JDK代理  trueCGlib代理

AOP的术语:

Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点.

Pointcut(切入点):所谓切入点是指我们要对哪些Joinpoint进行拦截的定义.

Advice(通知/增强):所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)

Introduction(引介):引介是一种特殊的通知在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field.

Target(目标对象):代理的目标对象

Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程.

spring采用动态代理织入,而AspectJ采用编译期织入和类装在期织入

Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类

Aspect(切面): 是切入点和通知(引介)的结合

Spring的AOP【原始的一套面向切面编程入门程序  给业务方法做增强(添加写日志功能)】

1.在注入完成的情况下

2.引入AOP的jar包

3.使用一套AOP原始的增强接口   【实现自己的增强功能】

  前置增强

//前置增强

public class Before implements MethodBeforeAdvice {

         private Logger logger=Logger.getLogger(Before.class);

 

         @Override         //方法对象               参数列表                 类型

         public void before(Method arg0, Object[] arg1, Object arg2)

                            throws Throwable {

                   logger.info("方法开始执行-------------------------");

                   System.out.println("类型为--------"+arg2);

                   System.out.println("方法名为--------"+arg0.getName());

                   System.out.println("方法的第一个参数--------"+arg1[0]);

         }

}


  后置增强

//后置增强

public class AfterReturning implements AfterReturningAdvice {

         private Logger logger=Logger.getLogger(AfterReturning.class);

         @Override                  

         public void afterReturning(Object arg0, Method arg1, Object[] arg2,

                            Object arg3) throws Throwable {

                   logger.info("方法执行完毕-----------------------------");

                   System.out.println("方法的返回值为--------"+arg0);

                   System.out.println("类型为--------"+arg3);

                   System.out.println("方法名为--------"+arg1.getName());

                   System.out.println("方法的第一个参数--------"+arg2[0]);

         }

}


  环绕增强

//环绕增强

public class Around implements MethodInterceptor {

         private Logger logger=Logger.getLogger(Around.class);

         @Override

         public Object invoke(MethodInvocation arg0) throws Throwable {

                   logger.info("环绕增强执行----------------------");

                   System.out.println("类型为--------"+arg0.getThis());

                   System.out.println("方法名为--------"+arg0.getMethod().getName());

                   System.out.println("方法的第一个参数--------"+arg0.getArguments()[0]);

                   //放出

                   return arg0.proceed();

         }

}


  异常增强

//异常增强    自定义增强方法

public class AfterThrowing implements ThrowsAdvice {

         private Logger logger=Logger.getLogger(AfterThrowing.class);

         //自定义对应异常类型的增强

         public void afterThrowing(Method arg1, Object[] arg2, Object arg3,Exception e) throws Throwable {

                   logger.info("开始异常增强-------------------------");

                   System.out.println("异常类型为--------------"+e);

         }

}


4.配置AOP增强

<!-- 前置增强的实例 --> 

   <bean id="before" class="common.Before"></bean>

   <!-- 后置增强的实例 --> 

   <bean id="afterreturning" class="common.AfterReturning"></bean>

    <!-- 环绕增强的实例 --> 

   <bean id="around" class="common.Around"></bean>

    <!-- 异常增强的实例 --> 

   <bean id="afterThrowing" class="common.AfterThrowing"></bean>

  

  

   <!-- aop的配置 -->

   <aop:config>

     <!-- 配置切点           切点表达式 -->

     <aop:pointcut expression="execution(* biz..add*(..))" id="pointcut"/>

     <!-- 织入 -->

     <aop:advisor advice-ref="before" pointcut-ref="pointcut" />

     <!-- 织入 -->

     <aop:advisor advice-ref="afterreturning" pointcut-ref="pointcut"/>

     <!-- 织入 -->

     <aop:advisor advice-ref="around" pointcut-ref="pointcut"/>

     <!-- 织入 -->

     <aop:advisor advice-ref="afterThrowing" pointcut-ref="pointcut"/>

   </aop:config>


execution()是最常用的切点函数,其语法如下所示:

整个表达式可以分为五个部分

如:* biz..*(..)

1、execution(): 表达式主体。

2、第一个*号:表示返回类型, *号表示所有的类型。

3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包

4、*(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数

Spring   AspectJ的AOP *****

是2.0之后的新版  而且spring对他提供了注解技术

 

1.在注入完成的情况下

2.引入AOP的jar包

3.自定义增强类

//增强类

public class Loggers {

         private Logger logger=Logger.getLogger(Loggers.class);

        

         //前置增强

         public void before(JoinPoint jp){

                   logger.info("方法开始执行--------------------------------");

                   System.out.println("类型为------"+jp.getTarget());

                   System.out.println("方法名为-------"+jp.getSignature().getName());

                   System.out.println("第一个参数为------"+jp.getArgs()[0]);

         }

        

         //后置增强

         public void afterReturning(JoinPoint jp,Object obj){

                   logger.info("方法执行结束--------------------------------");

                   System.out.println("类型为------"+jp.getTarget());

                   System.out.println("方法名为-------"+jp.getSignature().getName());

                   System.out.println("第一个参数为------"+jp.getArgs()[0]);

                   System.out.println("返回值类型是---------"+obj);

         }

        

        

         //环绕增强

         public Object around(ProceedingJoinPoint pjp) throws Throwable{

                   logger.info("方法开始环绕--------------------------------");

                   System.out.println("类型为------"+pjp.getTarget());

                   System.out.println("方法名为-------"+pjp.getSignature().getName());

                   System.out.println("第一个参数为------"+pjp.getArgs()[0]);

                   //抛出

                   return pjp.proceed();

         }

        

         //异常增强

         public void afterThrowing(JoinPoint jp,Exception e){

                   logger.info("方法出现异常--------------------------------");

                   System.out.println("类型为------"+jp.getTarget());

                   System.out.println("方法名为-------"+jp.getSignature().getName());

                   System.out.println("第一个参数为------"+jp.getArgs()[0]);

                   System.out.println("异常信息是---------"+e);

         }

         //最终增强  相当于 finally

         public void after(JoinPoint jp){

                   logger.info("方法最终执行--------------------------------");

                   System.out.println("类型为------"+jp.getTarget());

                   System.out.println("方法名为-------"+jp.getSignature().getName());

                   System.out.println("第一个参数为------"+jp.getArgs()[0]);

         }

}


  4编写xml配置文件

!-- 实例化增强的类 -->

   <bean id="log" class="common.Loggers"></bean>

   <!-- aop的配置 -->

   <aop:config>

     <!-- 切点 -->

     <aop:pointcut expression="execution(* biz..*(..))" id="pointcut"/>

     <!-- 织入 -->

     <aop:aspect ref="log">

       <!-- 这就是前置增强 -->

       <aop:before method="before" pointcut-ref="pointcut"/>

       <!-- 这就是后置增强 -->

       <aop:after-returning method="afterReturning" pointcut-ref="pointcut" returning="obj"/>

        <!-- 这就是环绕增强 -->

       <aop:around method="around" pointcut-ref="pointcut"/>

        <!-- 这就是异常增强 -->

       <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e"/>

        <!-- 这就是最终增强 -->

       <aop:after method="after" pointcut-ref="pointcut" />

      

     </aop:aspect>

   </aop:config>

Advisor和Aspect

Aspect可以指定多个方法的切入

 

现在的开发中 我们一般使用Aspect

 

AspactJ注解的配置

   @Aspect 指明这是一个增强类

   @Before前置增强

  @Afterreturning 后置增强

  @Around 环绕增强

  @AfterThrowing 异常增强

  @After 最终增强

 

Xml 中进行注解配置的交代

<beanclass="common.Loggers"></bean>

 <!--自动生成代理类  aop:cfg  -->

 <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 

 

Spring的JDBCTemplate

JDBCTemplate模板与dbutils比较类似

Spring对持久层技术的支持

       JDBC:org.springframework.jdbc.core.JdbcTemplate

Hibernate3.0:org.springframework.orm.hibernate3.HibernateTemplate

Mybatis   :org.springframework.orm.ibatis.sqlMapClientTemplate

JPA       :org.springframework.orm.jpa.JpaTemplate

 

开发JDBCTemplate入门

  第一步引入jar包

*spring-tx-3.2.0.RELEASE.jar

*spring-jdbc-3.2.0.RELEASE.jar

*数据库的驱动ojdbc6.jar  我现在演示用的oracle  ojdbc6.jar

 

第二步创建applicationContext.xml文件

 

第三歩 编写 测试类

 

Spring默认的数据源

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

     <property name="DriverClassName" value="oracle.jdbc.OracleDriver" />

     <property name="Url" value="jdbc:oracle:thin:@localhost:1521:ORCL"/>

     <property name="Username" value="laowang"/>

     <property name="Password" value="niit"/>

  </bean>


DBCP数据源

导入jar包:com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jar

          com.springsource.org.apache.commons.pool-1.5.3.jar

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">

     <property name="driverClassName" value="oracle.jdbc.OracleDriver" />

     <property name="url" value="jdbc:oracle:thin:@localhost:1521:ORCL"/>

     <property name="username" value="laowang"/>

     <property name="password" value="iit"/>

  </bean>

 

C3p0连接池

  导入jar包com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">

     <property name="driverClass" value="oracle.jdbc.OracleDriver" />

     <property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:ORCL"/>

     <property name="user" value="laowang"/>

     <property name="password" value="iit"/>

  </bean>

 

参数放在对应的配置文件中 引用到spring配置文件中

第一种

<!-- spring提供  解析jdbc.properties的类 -->

 <beanclass="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

    <property name="location"value="classpath:jdbc.properties"></property>

 </bean>

第二种

<context:property-placeholderlocation="classpath:jdbc.properties"/>

什么引用:如:value="${jdbc.driver}"

 

JDBCTemplate的CRUD操作

Spring框架中提供了对持久层的支持类

Jdbc:org.springframework.jdbc.core.support.JdbcDaoSupport

 

编写Dao的时候

注入:JdbcTemplatejdbcTemplate 类

 

进行CRUD操作

保存 update(String sql,Object ….args);

修改 update(String sql,Object ….args);

删除 update(String sql,Object ….args);

 

查询

简单查询

Selectcount(*) from user   --queryForInt(String sql)

Selectname from user where id=1  --queryForObject(Stringsql)


复杂查询 

返回对象  .queryForObject(sql, rowMapper, args)

返回集合  query(sql, owMapper);

 

内部类【把我们的result数据封装成想要的对象】

//编写内部类

         class UserRowMapper implements RowMapper<User>{

                   /*

                    * rs结果集

                    * rowNum 行号

                    */

                   @Override

                   public User mapRow(ResultSet rs, int rowNum) throws SQLException {

                            // TODO Auto-generated method stub

                            User user=new User();

                            user.setId(rs.getInt(1));

                            user.setName(rs.getString(2));

                            user.setPwd(rs.getString(3));

                            return user;

                   }

         }

Spring的事务管理

  什么是事务管理?

  事务:逻辑上的一组操作,要么都成功 要么都失败

 

事务的特性

  ACID

  原子性:事务不可分割  【要么都成功 要么都失败】

  一致性:事务执行前后,数据完整性保持一致【更新之后 数据的和不变】

  隔离性:一个事务执行的时候,不应该受其他事务的影响。

  持久性:事务一旦结束,数据就将永久的保存在 数据库

 

如果不考虑隔离性:

  脏读:一个事务读到另一个事务未提交的数据

  【刘升东转钱给张清元  张清元查看余额】

  不可重复读:一个事务读到另一个事务已提交的数据

  【update 导致一个事务多次查询的结果不一致】

   虚读:一个事务读到另一个事务已提交的数据

【insert 导致一个事务多次查询的结果不一致】

 

事务的隔离级别

  未提交读:以上情况都有可能发生【读的对快的  但是出现脏数据的可能性 最高的】

  已提交读:避免脏读,但不可重复读,虚读是有可能发生的

  可重复读:避免脏读,不可重复读,虚读可能发生

  串行读  :避免以上所有的情况  【读的最精准的 但是最慢的】

 

 

Spring中的事务管理

  分层开发:事务处在biz【业务 service】层

  Spring提供的事务管理的API

  PlatformTransactionManager: 平台事务管理器

TransactionStatusgetTransaction(TransactionDefinitiondefinition)  //获得事务

void commit(TransactionStatus status)  //提交事务

void rollback(TransactionStatus status)  //回滚事务

 TransactionDefinintion:事务的定义

ISOLATION_****:定义事务的隔离级别

PROPAGATION_****:定义事物的传播机制

TransactionStatus:事务的状态

  hasSavepoint()是否有保存点

  isNewTransaction()是否是一个新的事务

  isRollbackOnly() 事务是否以提交

 

三者的关系:PlatformTransactionManager通过TransactionDefinintion设置事务相关的信息,管理事务的过程中,产生的一些事务的状态TransactionStatus来记录

 

API的详解

   PlatformTransactionManager

   Spring为了不同的持久化框架提供了不同的实现类

   SpringJDBC或ibatis进行持久化时使用:

   org.springframework.jdbc.datasource.DataSourceTransactionManager

 

  hibernate3.0版本进行持久化时使用:

org.springframework.orm.hibernate3.HibernateTransactionManager

  

  JPA进行持久化时使用:

org.springframework.orm.jpa.JpaTransactionManager

  

 TransactionDefinintion:事务的定义接口

   Spring为事务的隔离级别/传播行声明了不同的常量表示

   【隔离常量】

   ISOLATION_DEFAULT :使用后端数据库默认的隔离级别【spring中的选项】

   ISOLATION_READ_COMMITTED 【oracle数据库默认的隔离级别 允许在并发事务提交后读取,可防止脏读,但是幻读和不可重复读任肯发生】

   ISOLATION_REPEATABLE_READ 【mysql 对于相同只读多次读取是一致的,除非数据被事务本身修改,可防止脏读,不可重复读,但是幻读可能发生】

   ISOLATION_READ_UNCOMMITTED 【允许你读取 还未提交的改变的数据 ,可能出现脏,幻,不可重复读】

   ISOLATION_SERIALIZABLE  【完全服从ACID的隔离级别  确保不发生 脏读/幻读/不可重复读。】

 

  【传播机制的常量】

   PROPAGATION_REQUIRED  支持当前事物,如果不存在  新建一个事务

   【A,B 如果A有事务,B就使用A的事务,,如果A没有事物,B就开启一个新的事务

(A,B在同一个事务中)

 

PROPAGATION_SUPPORTS  支持当前的事务,如果不存在,就不使用事务

【A,B  如果A有事务  B使用A的事务, 如果A没有事务  B就不使用事物】

 

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

  【A,B  如果A有事务 B就使用A的事务  如果A没有事务   抛出异常】

 

  PROPAGATION_REQUIRES_NEW  如果有事务存在挂起当前事务 创建新的事务

  【A,B 如果A有事务 B将A的事务挂起 重新创建新的事务

(A,B不在同一事务)】

 

PROPAGATION_NOT_SUPPORTED  如果存在事务挂起当前事务

【A,B  非事务的运行方式  A有事务 直接挂起当前的事务】

 

PROPAGATION_NEVER 不支持当前事务;如果当前事务存在,则抛出异常。

 

PROPAGATION_NESTED  如果当前存在事务 则嵌套事务执行

【基于:savePoint技术 保存点

 A,B  A有事务,A执行后,将A事务执行后的内容保存到SavePoint,如果B事物有异常的话,用户需要手动的设置事物是回滚还是提交。

 

常用的【***

 PROPAGATION_REQUIRED

PROPAGATION_REQUIRES_NEW

  Spring的事务管理:

Spring的事物管理分为2类

  1.编程式事务管理 【手动编程 敲代码完成事务管理】

  2.声明式事务管理 【不需要手动敲 配置即可】

 

 

使用spring的事物模拟银行转账功能

1.导入相应的jar包

2.配置 配置文件

  ApplicationContext.xml   log4j.properties   jdbc.properties

3.创建对应的接口和实现类

  Dao/biz

4.spring的事务管理

  手动编码完成事务的管理

  需要事务的管理器:真正管理事务的对象【commit/rollback….】

 

  Spring 还提供了事物管理的模板【工具类对事务的管理器的封装】

 

1.注册事务的管理器

<beanid="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource"></bean>

 

2.注册事务的模板

  <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate" p:transactionManager-ref="transactionManager"></bean>

 

3.把模板注入给biz

<bean id="userBiz" class="biz.UserBizImp" p:ud-ref="userDao" p:tt-ref="transactionTemplate"></bean>

 

4.biz更具模板开启事物/提交事物/回滚事务

tt.execute(new TransactionCallbackWithoutResult() {

                            @Override

                            protected void doInTransactionWithoutResult(TransactionStatus arg0) {

                                    

                                         ud.outMoney(outName, money);

                                    int i=1/0;

                                    ud.inMoney(inName, money);

                            }

 

缺点:代码量的增加    代码有侵入性   每一个业务先要用事物必须来一套

 

声明式事务管理:【基于切面的  自动代理  ***

1.导入相应的jar包

2.配置配置文件

  ApplicationContext.xml   log4j.properties   jdbc.properties

3.创建对应的接口和实现类

  Dao/biz

4.spring配置  增强/代理

  1.注册管理器

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource"></bean>

 

  2.定义增强类【事务管理】

<tx:advice id="txAdvice" transaction-manager="transactionManager">

     <!-- 增强事务的属性配置 -->

     <tx:attributes>

        <!-- 指定增强的方法

        isolation  事物额隔离级别

        propagation  事物的传播机制

        read-only  false为只读

        no-rollback-for  发生哪些异常不回滚

        rollback-for  发生哪些异常回滚

        -->

        <tx:method name="transfer*" />

     </tx:attributes>

  </tx:advice>

 

  3.定义aop的配置

<aop:config>

    <!-- 定义切点 -->

    <aop:pointcut expression="execution(* biz..*(..))" id="pointcut"/>

    <!-- 织入 -->

    <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />

  </aop:config>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值