Spring框架学习笔记

目录

Spring概念

Spring优势

体系结构

Spring IOC

开发步骤

Spring的相关API

ApplicationContext的相关继承体系

Bean标签配置

基本配置

范围配置

生命周期配置

实例化三种方法

Bean的依赖注入

引入其他配置文件

Spring配置数据源

数据源(连接池的作用)

数据源的开发步骤

Spring配置数据源

Spring JdbcTemplate

概述

JdbcTemplate开发步骤

spring产生JdbcTemplate对象

JdbcTemple的CURD操作

Spring 注解开发

Spring原始注解

Spring新注解

Spring集成Junit

Spring AOP 

概念

AOP的作用以其优势

AOP的底层实现

JDK动态代理方法

Cglib的动态代理

AOP相关概念

基于XML的AOP开发

开发步骤

切点表达式

通知类型

基于注解的AOP开发

开发步骤

注解通知的类型

切点表达式的抽取

Spring的事务控制

编程式事务控制相关对象

PlatformTransactionManager

TransactionDefinition

TransactionStatus

基于XML的声明式事务控制

定义

声明式事务处理的作用

声明式事务控制的实现

基于注解的声明式事务控制

使用注解配置声明式事务控制

注解配置声明式事务控制解析


Spring概念

        Spring是分层的JavaSE/EE应用full-stack轻量级开源框架,以IOC(Inverse Of Control:反转控制)和AOP(Aspect Oriented Programming: 面向切面编程)为内核。

         提供了展示层SpringMVM和持久层Spring JDBCTemplate 以及业务层事务管理等众多的企业应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE企业应用开源框架。

Spring优势

  • 方便解耦,简化开发
  • AOP编程的支持
  • 声明式事务的支持
  • 方便程序的测试
  • 方便集成各种优秀框架
  • 降低JavaEE API的使用难度

体系结构

Spring框架学习笔记_第1张图片

Spring IOC

开发步骤

步骤一:导入Spring开发的基本包maven坐标


        
            org.springframework
            spring-context
            5.0.5.RELEASE
        

        
            org.springframework
            spring-test
            5.0.5.RELEASE
        
    

步骤二:编写Dao/Mapper接口和实现类

步骤三:创建Spring核心配置文件(applicationContext.xml)

步骤四:在spring配置文件中配置相关Bean实体对象

步骤五:使用Spring的API获得Bean实例

Spring的相关API

ApplicationContext的相关继承体系

ApplicationContext:接口类型、代表应用上下文,可以通过其实例获得Spring容器中的Bean对象

Spring框架学习笔记_第2张图片

ApplicationContext的实现类

ApplicationContext有很多,以下介绍三种实现类

①ClassPathXmlApplicationContext

它是从类的根路径下加载配置文件

②FIleSystemXmlApplicationContext

它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。

③AnnotationConfigApplicationContext

当使用注解配置容器对象时,需要使用此类来创建Spring容器。它用来读取注解。

getBean()方法使用

Spring框架学习笔记_第3张图片

 ①当参数的数据类型是字符串时,表示根据Bean的id从容器中获得Bean实例,返回是Object需要强转。

②当参数的数据类型是Class类型时,表示根据类型从容器中匹配Bean实例,当容器中相同类型的Bean有多个时,则此方法会把报错。

Bean标签配置

Spring框架最重要就是配置Bean标签

基本配置

用于配置对象交由Spring来创建

默认情况下它调用的是类中的无参构造器,如果没有无参构造函数则不能创建成功。

基本属性:

id:Bean 实例在Spring容器中的唯一标识

class:Bean的全限定名称

用UserDaoImpl举例

步骤一:创建UserDaoImpl

//定义实现类

public class UserDaoImpl implements UserDao {

    //默认情况下创建空参
    public UserDaoImpl(){
        System.out.println("UserDaoImpl创建完成");
    }
    @Override
    public void save() {
        System.out.println("保存成功");
    }
}

配置applicationContext.xml文件



    

使用相关API,调用Bean

    public void test1(){
     //在资源路径下查找配置文件
     ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
     UserDao userDao = (UserDao) applicationContext.getBean("userDao");
     //调用相关方法
     userDao.save();
 }

范围配置

scope:指对象的作用范围,取值如下:

Spring框架学习笔记_第4张图片

 ①当scope的取值为singleton时

Bean的实例化个数为1个

Bean的实例化时机:当Spring核心文件被加载时,实例化配置的Bean实例

Bean的生命周期:

a.对象创建:当应用加载,创建容器时,对象被创建了

b.对象运行:只要容器时,对象一直活着

c.对象销毁:当应用卸载,销毁容器时,对象就被销毁了

②当scope的取值为prototype时

Bean的实例化个数为多个

Bean的生命周期:当调用getBean()方法时实例化Bean

a.对象创建:当调用getBean()方法时实例化Bean

b.对象运行:只要对象在使用中,就一直活着

c.对象销毁:当对象长时间不用时,被java的垃圾回收器回收了。

默认情况下scope值为singleton

生命周期配置

init-method:指定类中的初始化方法名称

destory-method:指定类中销毁方法名称

实例化三种方法

①无参构造方法实例化

 

②工产静态方法实例化

创建工厂类

public class StaticFactoryBean {
    public static UserDao createUserDao(){
        return new UserDaoImpl();
    }
}

相关配置


③工厂实例方法实例化

创建工厂类


public class DynamicFactoryBean {
    public UserDao createUserDao(){
        return  new UserDaoImpl();
    }

}

相关配置


    

    

Bean的依赖注入

定义:它是Spring框架核心IOC的具体实现。在编写程序时,通过控制反转,把对象的创建交给了Spring,但是代码中不可能出现没有依赖的情况。IOC解耦只是降低他们的依赖关系,但不会消除。例如:业务层仍会调用持久层的方法。那些这种业务员和持久层的依赖关系,在使用Spring之后,就让Spring来维护了,简单来说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。

以下是注入方法

①Set方法注入


    

        
    

也采用P命名空间代替Set方法注入

P命名空间注入本质也是set方法注入,但比起上述的set方法注入更加方便,主要体现在配置文件汇总,如下:首先,需要引入P命名空间:

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

其次,需要修改注入方法


    

②有参构造器注入


    

        
    

④普通数据类型的注入


    
        
        
    

说明:普通数据类型注入时用value,实体类型注入时要ref

⑤集合的注入

a.List注入


    
        
            
                小花
                小咪
            
        
    

    
        
            
                
                
            
        
    

采用标签进行注入

b.Map的注入

  

    
    

    
        
        
    

    
        
            

                
                
            
        
    

采用标签以及搭配使用

c.properties的注入


    
        
            
                小黄
                10
            
        
    

使用标签

引入其他配置文件

实际开发时,String的配置内容非常多,这就导致Spring配置很繁杂且体积很大,所以,可以将部分配置到其他配置文件中,而在spring主配置文件通过import标签进行加载。

使用方式如:

Spring配置数据源

数据源(连接池的作用)

当个方来说,就像餐厅里面的服务员,当餐厅来客人时,就有一个服务员来帮忙客人的点餐,送餐等,当客户用餐结束后离开,服务员也就可以回到之前的位置中,等待下一个客人。

数据源是指餐厅,存放着连接对象,而连接对象就指着是服务员,当一个请求来时,就会从连接池中拿出一个连接对象进行处理。处理完后,再将连接对象放回到数据源中。这样就可以减少每次连接数据库时的开销,不需要每次去请求数据库的连接。

数据源的开发步骤

①导入数据源的坐标和数据库驱动坐标


    
        mysql
        mysql-connector-java
        8.0.25
    

    
        com.mchange
        c3p0
        0.9.5.2
    

    
        com.alibaba
        druid
        1.1.10
    

②创建数据源对象

③设置数据源的基本连接数据

④使用数据获取连接资源和归还连接资源

  //加载配置文件
    Properties properties = new Properties();
    properties.load(new FileInputStream("src\\main\\resources\\jdbc.properties"));
    String driver = properties.getProperty("jdbc.driver");
    String url = properties.getProperty("jdbc.url");
    String user = properties.getProperty("jdbc.user");
    String password = properties.getProperty("jdbc.password");
    //创建连接对象
    DruidDataSource dataSource = new DruidDataSource();
    //配置连接
    dataSource.setDriverClassName(driver);
    dataSource.setUrl(url);
    dataSource.setUsername(user);
    dataSource.setPassword(password);
    DruidPooledConnection connection = dataSource.getConnection();
    System.out.println(connection);
    //归还连接
    connection.close();

Spring配置数据源

可以将DataSource的创建权交由Spring容器去完后。

首先,需要引入context命名空间和约束路径

命名空间:xmlns:context = "http://www.springframework.org/schema/context"

约束路径:http://www.springframework.org/schema/context                                         http://www.springframework.org/schema/context/spring-context.xsd





    
        
        
        
        
    

spring中也提供一些jdbc的方法就是JdbcTemplate

Spring JdbcTemplate

概述

它是spring框架中提供的一个对象,是对原始繁琐的jdbc API对象的简单封装。Spring框架为我们提供了很多的操作模板类。例如:操作关系型数据的JdbcTemplate和HibernateTemplate,操作nosql数据库的RedisTemplate,操作消息队列的JmsTemplate等等。

JdbcTemplate开发步骤

①导入Spring-jdbc和spring-tx坐标

②创建数据库表和实体

③创建JdbcTemplate对象

④执行数据库操作

spring产生JdbcTemplate对象

我们可以JdbcTemplate的创建全交给Spring,将数据源DataSource的创建权也交给Spring,在Spring容器内部将数据源DataSource注入到JdbcTemplate模板对象中。



    
    
    
    



    
        
    

JdbcTemple的CURD操作

①Insert操作

    public void Test01(){
        //导入applicationContext.xml文件
         ApplicationContext applicationContext = 
                new ClassPathXmlApplicationContext("applicationContext.xml");
        //调用容器中的JdbcTemplate对象
       JdbcTemplate jdbcTemplate = 
                (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
        //测试
      jdbcTemplate.update("insert into account values(?,?)","xiaoha",3000);
    }

②update操作

    @Test
    //更新操作
    public void Test02(){
        //导入applicationContext.xml文件
        ApplicationContext applicationContext = 
                 new ClassPathXmlApplicationContext("applicationContext.xml");
        //调用容器中的JdbcTemplate对象
        JdbcTemplate jdbcTemplate = 
                (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
        //测试
        jdbcTemplate.update("update account set money = ? where name = ?",5000,"xiaoha");
    }

 ③delete操作

  public  void  Test03(){
        //导入applicationContext.xml文件
        ApplicationContext applicationContext = 
                new ClassPathXmlApplicationContext("applicationContext.xml");
        //调用容器中的JdbcTemplate对象
        JdbcTemplate jdbcTemplate = 
                   (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
        //测试
        jdbcTemplate.update("delete from account where name = ?","xiaoha");
    }

④select操作

a.查询所有/多条数据

 public void Test04(){
        //导入applicationContext.xml文件
        ApplicationContext applicationContext = 
                    new ClassPathXmlApplicationContext("applicationContext.xml");
        //调用容器中的JdbcTemplate对象
        JdbcTemplate jdbcTemplate = 
                (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
        //测试
        List accountList = 
           jdbcTemplate.query("select * from account",
             new BeanPropertyRowMapper<>(Account.class));
        for (Account account : accountList) {
            System.out.println(account);
        }

    }

b.查询一条数据

  @Test
    //查询一条记录
    public void Test05() {
        //导入applicationContext.xml文件
        ApplicationContext applicationContext = 
                new ClassPathXmlApplicationContext("applicationContext.xml");
        //调用容器中的JdbcTemplate对象
        JdbcTemplate jdbcTemplate = 
                (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
        //测试
        Long accountNum = jdbcTemplate.queryForObject
                            ("select count(*) from account", Long.class);
        System.out.println(accountNum);
    }

JdbcTemplate小结:

①导入Spring-jdbc和spring-tx坐标

②创建数据库表和实体

③创建jdbcTemplate对象

JdbcTemplate jdbcTemplate = new JdbcTemplate()

jdbcTemplate. setDataSoure(dataSource)

④执行数据操作

更新操作:

        jdbcTemplate.quate(sql.params)

查询操作:

        jdbc.Template.query(sql,Mapper,params)  

        jdbc.Template.queryForObject(sql,Mapper,params)

Spring 注解开发

之前所用的都是配置文件的方法,比较的麻烦,因此Spring提供也一种注解的方法来简化开发。

Spring原始注解

Spring是轻代码而配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xml配置文件可以简化配置,提高开发效率。

spring原始注解主要是替代的配置

常见的配置注解

  • @Component : 使用在类上用于实例化Bean
  • @Controller:使用在Web层类(控制层)上用于实例化Bean
  • @Service: 使用在service层类上用于实例化Bean
  • @Repository:使用dao层类上用于实例化Bean
  • @Autowired:使用字段上用于根据类型依赖注入
  • @Qualifier:结合@Autowried一起使用用于根据名称进行依赖注入
  • @Resource:相当于@Autowired+@Qualifier,按照名称进行注入
  • @value:注入普通属性
  • @Scope:标注Bean的作用范围
  • @PostConstruct:使用在方法上标方法时Bean的初始化方法
  • @PreDestory:使用在方法上标注方法时Bean的销毁方法

注意:使用注解进行开发时,需要在applicationContext.xml中配置组件扫描,作用是指定哪个包及子包下的Bean需要进行扫描以便识别使用注解配置的类、字段和方法


参数问题:一般注解参数一般使用value表示id,但是Resource是用name表示id

Spring新注解

使用上面的注解还不能全部替代xml配置文件,还需要使用注解替代的配置如下:

非自定义的Bean的配置:

加载properies文件的配置:

组件扫描的配置:

引入其他文件:

  • @Configuration:用于指定当前类是一个Spring配置类,当创建容器时会类上加载注解
  • @ComponentScan:用于Spring在初始化容器时要扫描的包。  作用和在Spring的xml配置文件中的一样
  • @Bean:使用在方法上,标注将该方法的返回值存储到Spring容器中
  • @import:用于导入其他配置类 

Spring集成Junit

在测试类中,每个方法都有以下两行

ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml")

IAccountService as  = ac.getBean("accountService",IAccountService.class);

这两行代码的作用是容器,如果不写的话,直接会提示空指针异常。所以又不能轻易删掉。

解决方法

①让SpringJunit负责创建Spring容器,但是需要将配置文件的名称告诉它

②将需要进行测试Bean直接在测试类中进行注入

Spring集成JUnit步骤

①导入Spring集成Junit的坐标

②使用@RunWith注解替换原来的运行期

③使用@ContextConfiguration指定配置文件或配置类

④使用@Autowired注入需要测试的对象

⑤创建测试方法进行测试

文件注入:

@ContextConfiguration("classpath:applciation.Context.xml")

注解注入:

@ContextConfiguration(class={SpringConfiguration.class)

Spring AOP 

概念

AOP为Aspect Oriented Programming的缩写,意思为面向切面编程,是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术

AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生泛型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重复性、同时提高了开发的效率。

AOP的作用以其优势

作用:在程序运行期间,不修改源码的情况下对方进行功能增强。

优势:减少重复代码,提高开发效率,并且便于维护

AOP的底层实现

实际上,AOP的底层通过Spring提供的动态技术实现。在运行期间Spring通过动态代理技术的生成代理对象,代理对象方法执行时进行增强功能的介入,在去调用的方法,从而完成功能的增强。

采用的动态代理方法有两种

JDK动态代理方法

JDK代理:基于接口的动态代理技术

Spring框架学习笔记_第5张图片

原理步骤:

①编写目标类接口

public interface TargetInterface {
    public void method();
}

②编写目标类

public class Target implements TargetInterface{

    @Override
    public void method() {
        System.out.println("Target Running");
    }
}

③编写动态代理

 Target target  = new Target();
        TargetInterface proxy = (TargetInterface) 
                    Proxy.newProxyInstance(
                //目标对象类加载器
                target.getClass().getClassLoader(),
                //目标对象相同的接口字节对象数组
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    //调用代理对象的任何方法,实际执行的都是invoke方法
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) 
           throws Throwable {
                        //前置增强
                       System.out.println("前置代码增强");
                        Object invoke = method.invoke(target, args);//执行目标方法
                        //后置增强
                        System.out.println("后置代码增强");
                       return invoke;
                    }
                }
        );

Cglib的动态代理

基于父类的动态代理技术

Spring框架学习笔记_第6张图片

原理步骤: 

①编写目标类

public class Target {

    public void save() {
        System.out.println("save running...");
    }
}

②编写动态代理

  Target target  = new Target();
        //返回值就是动态生成的代理对象,基于cglib
        //1,创建增强器
        Enhancer enhancer = new Enhancer();
        //2.设置父类(目标)
        enhancer.setSuperclass(Target.class);
        //3.设置回调
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object proxy, Method method, 
        Object[] objects, MethodProxy methodProxy) throws Throwable {
                //执行前置
               System.out.println("前置增强代码");
                Object invoke = method.invoke(target, args);
                //执行后置
                System.out.println("后置增强代码");
                return invoke;
            }
        });

AOP相关概念

Spring的AOP实现底层就是对上面的动态代码的代码进行了封装,封装后我们只需要关注的部分进行代码编写,并通过配置的方式完成指定目标的方法增强。

AOP的相关术语:

  • Target(目标对象):代理的目标对象
  • Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类
  • JoinPoint(连接点):所谓连接点是指那些被拦截到的点。在Spring中,这些点指的是方法,因为Spring只支持类型的连接点(可以被增强方法)
  • Pointcut(切入点):所谓切入点指我们要对哪些Joinpoint进行拦截的定义(增强方法)
  • Advice(通知/增强):所谓通知是指拦截到joinpoint之后所要做的事情就是通知
  • Aspect(切面):是切入点和通知的结合
  • Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程。Spring采用动态代理织入,而Aspect采用编译期织入和类装载期织入

基于XML的AOP开发

开发步骤

①导入AOP相关坐标

由于aop中封装了aspectj,因此也要导入aspectj相关坐标



org.springframework
spring-context
5.0.5.RELEASE



org.aspectj
aspectjweaver
1.8.13

②创建目标接口和目标类(内部有切点)

public interface TargetInterface {
    public void method();
}
public class Target implements TargetInterface{

    @Override
    public void method() {
        System.out.println("Target Running");
    }
}

③创建切面类(内部有增强方法)

public class Advice {
    public void Before(){
        System.out.println("前置增强方法");
    }
}

④将目标类和切面类的对象创建权交给Spring


    

    

⑤在applicationContext.xml中配置织入关系

导入aop命名空间

 xmlns:aop="http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop.xsd

配置切点表达式和前置增强的织入关系

   
    
        
        
            
          
    
        
    

切点表达式

表达式语法:

execution([修饰符] 返回值类型 包名.类名.方法名(参数))

注意:

访问修饰符可以省略

返回值、包名、类名、方法名可以使用星号*代表任意

包名与类名之间一个点代表当前包下的类,两个点..表示当前包及其子包下的类

参数列表可以使用两个点..表示任意个数,任意类型的参数列表

Spring框架学习笔记_第7张图片

 第一行表示com.itheima.aop包下的Target类下的返回类型为void的method方法

第二行表示com.itheima.aop包下的Target类下的返回类型为void的所有方法

第三行表示com.itheima.aop包下的所用方法

第四行表示com.itheima.aop包下以及子包下的所有方法

第五行表示第一层目标下以及第二层目录下的所有方法

通知类型

通知的配置语法:

名称 标签 说明 前端通知 用于前置通知,指定增强的方法切入点之前执行 后置通知 用于配置后置通知,指定增强在切入点方法之后执行 环绕通知 用于配置环绕通知。指定增强的方法在切点之前和之后都执行 异常抛出通知    用于配置异常抛出通知,指定增强的方法出现异常时执行 最终通知 用于配置最终通知,无论增强方法执行是否有异常都会执行

当多个增强的切点表示式相同时,可以将切点表达式进行抽取,在增强使用pointcut-ref属性代替来引用抽取的切点表达式


    

        
            

           
        
    

基于注解的AOP开发

开发步骤

①创建目标接口和目标类(内部有切点)

//定义目标接口

public interface TargetInterface {
public void method();
}
//定义实现类

public class Target implements TargetInterface {
@Override
public void method() {
System.out.println("Target running....");
}
}

②创建切面类(内部有增强方法)

public class MyAspect {
//前置增强方法
public void before(){
System.out.println("前置代码增强.....");
}
}

③将目标类和切面类的对象创建权交给Spring

@Component("target")
public class Target implements TargetInterface {
@Override
public void method() {
System.out.println("Target running....");
}
}
@Component("myAspect")
public class MyAspect {
public void before(){
System.out.println("前置代码增强.....");
}
}

④在切面类中使用注解配置织入关系

@Component("myAspect")
@Aspect
public class MyAspect {
@Before("execution(* com.itheima.aop.*.*(..))")
public void before(){
System.out.println("前置代码增强.....");
}
}

⑤在配置文件中开启组件扫描和AOP的自动代理




注解通知的类型

通知的配置语法:@通知注解(“切点表达式”)

名称 注解 说明
前置通知 @Before 用于配置前置通知,指定增强的方法在切入点方法之前执行
后置通知 @AfterReturning 用于配置后置通知,指定增强的方法在切入点方法之后执行
环绕通知 @Around 用于配置通知。指定增强的方法在切入点方法之前和之后都执行
异常抛出通知 @AfterThrowing 用于配置异常抛出通知。指定增强的方法在出现异常进行。
最终通知 @After 用于配置最终通知,无论增强方法执行是否有异常都会执行

切点表达式的抽取

同xml配置aop一样,我们将切点表达式抽取。抽取方式是在切面内定义方法,在该方法上使用@Pointcut注解定义切点表达式,然后在增强注解中进行引用,具体如下:

@@Component("myAspect")
@Aspect
public class MyAspect {
@Before("MyAspect.myPoint()")
public void before(){
System.out.println("前置代码增强.....");
}
@Pointcut("execution(* com.itheima.aop.*.*(..))")
public void myPoint(){}
}

Spring的事务控制

编程式事务控制相关对象

PlatformTransactionManager

PlatformTransactionManager接口是Spring的事务管理器,它里面提供了我们常用的操作事务的方法。

  • TransactionStatus getTransaction(TransactionDefination defination):获取事务的状态信息
  • void commit(TransactionStatus status):提交事务
  • void rollback(TransactionStatus status) :回滚事务

注意:

platformTransactionManager是接口类型,不同的DAO层技术则有不同的实现类。

例如:

DAO层技术是jdbc或mybatis时:

org.springframework.jdbc.datasource.DataSourceTransactionManager

DAO层技术是hibernate时:

org.springframework.ormhibernate5.HibernateTransactionManager

TransactionDefinition

TransactionDefinition是事务的定义信息对象,里面有如下方法:

  • int getIoslationLevel():获得事务的隔离级别
  • int getPropogationBehavior():获得事务的传播行为
  • int getTimeout():获得超时时间
  • boolean isReadOnly():是否只读

事务隔离级别

设置隔离级别,可以解决事务并发产生的问题,如脏读、不可重复读和虚读

  • ISOLATION_DEFAULT:默认
  • ISOLATION_READ_UNCOMMITTED:读取未提交内容
  • ISOLATION_READ_COMMITTED:读取提交内容
  • ISOLATION_REPEATABLE_READ:可重读
  • ISOLATION_SERIALIZABLE:可串行化

事务传播行为

  • REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。一般的选择(默认值)
  • SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行
  • MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常
  • REQUERS_NEW:新建事务,如果当前在事务中,把当前事务挂起。
  • NOT_SUPPORTED:已非事务方式执行操作,如果当前存在事务,就把当前事务挂起
  • NEVER:以非事务方式运行,如果当前存在事务,抛出异常
  • NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行REQUIRED类似的操作
  • 超时时间:默认值是-1,没有超时限制。如果有,以秒为单位进行设置
  • 是否只读:建议查询设置为只读

TransactionStatus

TransactionStatus接口提供的事务具体的运行状态,方法介绍如下:

  • boolean hasSavepoint():是否存储回滚点
  • boolean isComplete():事务是否完成
  • boolean isNevTransation():是否是新事务
  • boolean isRollbackOnly():事务是否回滚

基于XML的声明式事务控制

定义

Spring的声明式事务顾名思义就是采用声明的方法来处理事务。这里所说的声明,就是指在配置文件中声明,用在Spring配置文件中声明式的处理事务来代替代码式的处理事务。

声明式事务处理的作用

事务管理不侵入开发的组件,具体来说,业务逻辑对象就不会意识到正在事务管理之中,事实上也应该如此,因为事务管理是属于系统层面的服务,而不是业务逻辑的一部分。如果想要改变事务管理策划的话。也只需要在定义中重新配置即可。

在不需要事务管理的时候,只要在设立文件上修改一下,即可移去事务管理服务,无需改变代码重新编译,这样维护起来极其方便。

声明式事务控制的实现

声明式申明控制明确事项:

谁是切点?

谁是通知?

配置切面?

①引入tx空间

 xmlns:tx="http://www.springframework.org/schema/tx"
http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx.xsd

②配置事务增强


    
        
    



       
           
           
           
           
           
       


    
        
    

③配置事务 AOP 织入






其中,代表切点方法的事务参数的配置,例如:

  • name :切点方法名称
  • isolation:事务的隔离级别
  • propogation:事务的传播行为
  • timeout:超时时间
  • read-only:是否只读

基于注解的声明式事务控制

使用注解配置声明式事务控制

①编写dao


@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;


    public void out(String outMan, double money) {
        jdbcTemplate.update("update account set money=money-? 
                    where name=?",money,outMan);
    }

    public void in(String inMan, double money) {
        jdbcTemplate.update("update account set money=money+? 
            where name=?",money,inMan);
    }
}

②编写service

@Service("accountService")
public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountDao accountDao;
    @Transactional(isolation = Isolation.REPEATABLE_READ,propagation = 
            Propagation.REQUIRED)
    public void transfer(String outMan, String inMan, double money) {
        accountDao.out(outMan,money);
        int i  = 1/0;
        accountDao.in(inMan,money);
    }
}

③编写applicationContext.xml配置文件




    
        
    


    
    

注解配置声明式事务控制解析

①使用@Transactional在需要进行事务控制的类或方法上修饰,注解可用的属性同xml配置方式,例如隔离级别、传播行为等。

②注解使用在类上,那么该类下的所有方法都使用同一套注解参数配置

③使用在方法上,不同的方法可以采用不同的事务参数配置

④xml配置文件中要开启事务的注解驱动

你可能感兴趣的:(spring)