栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring框架

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring框架

Spring框架 1.spring介绍

spring是一个非常活跃的开源框架。基于IOC和aop来构架多层javaee系统,以帮助分离项目组件之间的依赖关系(解耦)
底层:工厂模式+xml

2.spring作用

Spring ioc能帮我们根据配置文件创建及组装对象之间的依赖关系
Spring aop能帮助我们无耦合的实现日志记录,性能统计,安全控制
Spring能非常简单的帮助我们管理数据库事务
Spring提供了与第三方数据访问框架无缝连接,比如Hibernate,mybatis,而且自己也提供了一套jdbc模板用来数据的访问
Spring还提供了与第三方web框架的无缝连接,比如Structs,并且自己也提供了一套springMVC框架,来方便web层搭建

3.spring框架组成

IOC和DI 1.IOC-控制反转

是降低对象之间的耦合关系的设计思想
通过IOC,开发人员不需要关心对象的创建过程,交给Spring容器完成,程序读取Spring配置文件,获取需要创建的bean对象,通过反射机制创建对象的实例

2.DI-依赖注入

Spring容器负责被调用者实例,实例创建后又负责将该实例注入调用者

入门程序 1.创建一个Maven项目 2.添加Spring相关jar包

  org.springframework
  spring-core
  4.3.18.RELEASE


  org.springframework
  spring-beans
  4.3.18.RELEASE


  org.springframework
  spring-context
  4.3.18.RELEASE


  org.springframework
  spring-context-support
  4.3.18.RELEASE


  org.springframework
  spring-expression
  4.3.18.RELEASE

3.创建java类

main文件夹新建一个java文件夹,设置文件夹的功能(make directory as)

4.1创建配置文件

main文件夹新建一个resources文件夹,设置文件夹的属性

4.2新建spring配置文件

5.测试

在src文件夹下,创建与main同级的文件夹test,设置test文件夹的的功能

bean标签的各种属性的使用 1. id 和 name属性


java代码

//创建一个IOC容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/applicationContext.xml");
//从容器中获取bean对象
//根据id来获取对象
Drink drink_01=applicationContext.getBean("drink_01",Drink.class);
//根据name获取对象,两种方式在单例模式下效果一样
Drink drink_02=applicationContext.getBean("drink_02",Drink.class);
2. scope属性


测试

//创建一个IOC容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/applicationContext.xml");
//从容器中获取bean对象
//根据id来获取对象
Drink drink_01=applicationContext.getBean("drink_01",Drink.class);
//根据name获取对象
Drink drink_02=applicationContext.getBean("drink_02",Drink.class);
System.out.println(drink_01==drink_02);//返回false
3. laze-init属性

配置


lazy-init=“false”

 public void test(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/applicationContext.xml");
        System.out.println("在获取对象之前");
        Drink drink_01=applicationContext.getBean("drink_01",Drink.class);
        Drink drink_02=applicationContext.getBean("drink_02",Drink.class);
        System.out.println("在获取对象之后");
        //测试结果:false 不延迟创建,在创建ApplicationContext时就创建了对象

    }

lazy-init=“true”

 public void test(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/applicationContext.xml");
        System.out.println("在获取对象之前");
        Drink drink_01=applicationContext.getBean("drink_01",Drink.class);
        Drink drink_02=applicationContext.getBean("drink_02",Drink.class);
        System.out.println("在获取对象之后");
        //测试结果:true 延迟创建,只在获取的时候创建

    } 
4. init-method(初始化) 和destroy-method(销毁)

创建对象的三种方式 1.通过构造方法创建(默认调用的是无参的构造方法)

2.通过静态工厂创建

在整合第三方框架时,需要创建第三方框架中的类的对象,而这个类的的构造方法并没有提供,只提供了静态工厂和工厂中的创建这个对象的方法,这个时候只能通过静态工厂来创建对象。



测试通过静态工厂创建对象

@Test
public void testStaticFactory(){

    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/applicationContext.xml");
   Drink drink = applicationContext.getBean("drink_staticFactory_create",Drink.class);
   System.out.println(drink);

}
3.通过非静态工厂创建





测试通过非静态工厂创建对象

@Test
public void testFactory(){

    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/applicationContext.xml");
    Drink drink = applicationContext.getBean("drink_factory_create",Drink.class);
    System.out.println(drink);

}
依赖注入 1.通过属性标签property注入

property标签
name:属性名 value:属性值 ref:依赖的对象id

public class Drink {
    private String name;
    private String sugar;
    private float price;

    public String getName() {
        return name;
    }

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

    public String getSugar() {
        return sugar;
    }

    public void setSugar(String sugar) {
        this.sugar = sugar;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    public Drink() {
        System.out.println("创建一杯饮料");
    }

    public Drink(String name) {
        this.name = name;
    }

    public Drink(String name, String sugar) {
        this.name = name;
        this.sugar = sugar;
    }

    public Drink(String name, float sugar) {
        this.name = name;
        this.price = sugar;
    }
    @Override
    public String toString() {
        return "Drink{" +
                "name='" + name + ''' +
                ", sugar='" + sugar + ''' +
                ", price=" + price +
                '}';
    }
}


    
    
    






    

2.通过构造函数注入

constructor-arg标签:
name:构造函数的参数名
value:传进去的值
ref:参数依赖的对象


    



    
    

3.通过p空间注入

引入p空间:xmlns:p=“http://www.springframework.org/schema/p”



p:属性名=属性值


4.复杂类型注入
package com.test.pojo;

import java.util.List;
import java.util.Map;
import java.util.Properties;

public class AA {
    private int arr[];
    private Drink drinkArr[];
    private List stringList;
    private List drinkList;
    private Map drinkMap;
    private Properties properties;


}





    
        
            1
            2
            3
        
    
    
    
        
            
            
            
        
    

    
        
            name
            sex
            age
        
    

    
        
            
            
            
        
    

    
        
            
            
            
        
    

    
        
            com.mysql.jdbc.Driver
            jdbc:mysql://localhost:3306/baidu
        
    

    

5.spel表达式注入

需要jar包


  org.springframework
  spring-expression
  4.3.18.RELEASE

import com.test.pojo.Drink;

import java.util.ArrayList;
import java.util.List;

public class TestSpel {
    public List getDrinkList(){

        List list = new ArrayList();
        list.add(new Drink("酸奶"));
        list.add(new Drink("橙汁"));
        return  list;
    }


    public static List getDrinkList2(){

        List list = new ArrayList();
        list.add(new Drink("酸奶2"));
        list.add(new Drink("橙汁2"));
        return  list;
    }
}



        
        



        

用注解的方式实现IOC 1.配置注解扫描


        
    

2.常用的注解

2.1用来创建对象的注解
@Component
创建一个对象(组件)
@Service
创建Service层对象
@Controller
创建控制层对象

//创建一个Service层对象,对象名为drinkService
@Service
//或者
@Service("自己设定的名字")
public class DrinkService implements IDrinkService {
    }

2.2用来注入的注解
2.2.1注入对象的方式1
@Autowired 根据类型注入
@Qualifier(“对象名”)
指定注入对象(如果满足注入对象有多个的时候)
2.2.2注入对象方式2
Resource(name=“对象名”)
根据对象名注入,相当于@Autowired+@Qualifie
2.2.3注入普通值
@Value(“数值”)

//    自动注入
    @Autowired
//    指定注入对象(如果满足注入对象有多个的时候)
    @Qualifier("oracleDrinkDao")*/
//自动注入方式2 ,相当于上面2个的结合
    @Resource(name="oracleDrinkDao")

2.3其他注解
@Scope
设置对象的作用域,默认是单例,可以设置为多例
@Scope(scopeName=“prototype”)
@Laze
设置为懒加载 前提是单例模式

//设置是否是懒加载
@Lazy
//可以设置对象的作用域 默认是单例
//@Scope(scopeName = "prototype")
@Component
public class Drink {
    @Value("橙汁")
    private String name;
    @Value("多糖")
    private String sugar;
    @Value("15")
    private float price;
    }
Spring JDBC数据访问

Spring JDBC 是Spring所提供的持久层技术,它的主要目标是降低使用JDBC API的门槛,以一种更直接、更方便的方式使用JDBC API,在Spring JDBC里,仅需做那些与业务相关的DML操作,而其他工作交给Spring JDBC.

1.JDBC Template的使用
导入jar包

  mysql
  mysql-connector-java
  5.1.38


  com.mchange
  c3p0
  0.9.5.2


  org.springframework
  spring-jdbc
  4.3.18.RELEASE

 @Test
    public void test(){
//        创建一个连接池
        ComboPooledDataSource comboPooledDataSource =new ComboPooledDataSource();
        try {
            comboPooledDataSource.setDriverClass("com.mysql.jdbc.Driver");
            comboPooledDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/ssm");
            comboPooledDataSource.setUser("root");
            comboPooledDataSource.setPassword("123456");
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }
//        创建一个JDBC Template对象
        JdbcTemplate jdbcTemplate =new JdbcTemplate(comboPooledDataSource);
        
//        执行sql语句
        String sql="insert into users values(null,?,?)";
        jdbcTemplate.update(sql,"timi","123456");
    }
2、用Spring创建ComboPooledDataSource对象和JdbcTemplate对象
applicationContext.xml配置文件
 

    
    

    
        
        
        
        
    


    
        
    

db.properties文件

driverClass=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql://localhost:3306/ssm
user=root
password=123456
3、JDBCTemplate的查询方法
//    查询 返回单个对象
    public  int selectUsersCounts(){
        String sql = "select count(*) from users";
        int num = jdbcTemplate.queryForObject(sql,Integer.class);
        return num;

    }
//    查询 返回集合
    public List selectAllUsers(){
        String sql = "select * from users";
        List usersList =jdbcTemplate.query(sql, new RowMapper() {
//            遍历结果集,将结果集中的每条数据组装成Users对象
            @Override
            public Users mapRow(ResultSet resultSet, int i) throws SQLException {
                return rowMapperHander(resultSet);
            }
        });
                return usersList;
    }
    public Users rowMapperHander(ResultSet resultSet){
        Users users =new Users();
        try {
            users.setUid(resultSet.getInt("uid"));
            users.setUname(resultSet.getString("uname"));
            users.setPassword(resultSet.getString("password"));

        } catch (SQLException e) {
            e.printStackTrace();
        }
        return users;

    }
@Test
public void test2(){
    ApplicationContext applicationContext=new ClassPathXmlApplicationContext("/applicationContext.xml");
    UsersDao usersDao=applicationContext.getBean("usersDao", UsersDao.class);

   int num= usersDao.selectUsersCounts();
   System.out.println(num);


}
@Test
public void test3(){
    ApplicationContext applicationContext=new ClassPathXmlApplicationContext("/applicationContext.xml");
    UsersDao usersDao=applicationContext.getBean("usersDao", UsersDao.class);

    List users=usersDao.selectAllUsers();
    System.out.println(users);

}
Spring中AOP的开发 一、AOP介绍

1.AOP介绍
AOP(Aspect Oriented Programming ),即面向切面编程。AOP技术利用一种横切技术,剖开封装对象的内部,并将那些影响了多个类的公众行为封装到一个可重用的模块,即切面。AOP把软件系统分为两部分:核心关注点和切面关注点。业务处理的主要流程是核心关注点,与之关注不大的是部分是横切关注点。横切关注点的一个特点是,它们经常发生在核心关注点的多处,而各处基本相似。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开。
2、AOP核心概念

. 连接点
程序执行的某一个特定位置,如类开始初始化之前,类初始化后,类中某一个方法调用前或后,方法抛出异常后,一个类或一段程序代码拥有一些具有边界性质的特定点,即称为连接点,spring仅支持方法连接点,即仅能在方法调用前,方法调用后,方法抛出异常,以及方法调用前后这些程序执行点织入增强。
. 切点
特定的连接点
.增强
增强是织入目标类连接点上的一段程序代码,在spring中,增强不仅可以描述程序代码,还拥有和另一个连接点相关的信息,即执行点的方位,结合执行点的方位信息和切点信息,就可以找到特定的连接。
.目标对象
增强逻辑的织入目标类
.织入
将增强添加到目标类具体的连接点上的过程。
AOP有三种织入方式:
1. 编译期织入,需要使用特殊的java编译器
2.类装载期织入,要求使用特殊的类装载器
3.动态代理织入,在运行期为目标类添加增强生成子类的方式。
.代理
一个类被AOP织入增强后,就产生了一个结果类,他是融合了原类和增强逻辑的代理类。
.切面
切面由切点和增强组成,它既包括横切逻辑的定义,也包括链接点的定义。
AOP的工作重心在于如何将增强应用于目标对象的连接点上,包含两项工作:
1.如何通过切点和增强定位到链接点上
2.如何在增强中编写切面代码
.通知类型
1.前置通知:目标方法运行之前调用
2.成功返回通知:在目标方法运行之后调用
3.环绕通知:在目标方法之前和之后都调用
4.异常拦截通知:如果出现异常,就会调用
5.后置通知:在目标方法运行之后调用

3.Spring AOP基础知识
两种代理机制:

JDK的动态代理:针对实现了接口的类产生代理CGlib的动态代理:针对没有实现接口的类产生代理 二、代理模式

1.静态代理
原理:创建一个代理类实现目标类的接口,在代理类中实现目标类中的对象
创建一个接口

public interface IUserService {
    public void insert();
}

创建一个目标类

//目标类
public class UserService implements IUserService{

    @Override
    public void insert() {
        System.out.println("添加用户");
    }
}

创建一个代理类

public class UserServiceProxy implements IUserService{
//    在代理类中存放一个目标类的对象
   private IUserService userService =new UserService();
    @Override
    public void insert() {
        System.out.println("添加开始前:"+new Date());
        userService.insert();
        System.out.println("添加结束前:"+new Date());

    }
}

测试

public class TestStaticProxy {
    @Test
    public void test(){
        IUserService userService =new UserServiceProxy();
        userService.insert();
    }
}

2.动态代理
可以代理不同的对象
1.jdk自带的代理方式
必须有接口
创建一个接口

public interface IUserService {
    public void insert();
}

创建目标类

//目标类
public class UserService implements IUserService {

    @Override
    public void insert() {
        System.out.println("添加用户");
    }
}

创建一个代理类生成器

//代理类生成器
public class Handler implements InvocationHandler {
//    存放目标对象
        Object object;
//    传进目标对象
    public Handler(Object object) {
        this.object = object;
    }
//    根据传递进来的目标对象生产代理对象 返回
    public static Object blind(Object object) {
        return Proxy.newProxyInstance(Handler.class.getClassLoader(),
                object.getClass().getInterfaces(),
                new Handler(object));
    }

    //实现代理类中重写接口中的方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("添加开始前:"+new Date());
//        调用目标对象的方法
        Object subject=method.invoke(object,args);
        System.out.println("添加开始前:"+new Date());
        return subject;
    }
}
测试
public class TestJdkProxy {
    @Test
    public void test(){
       IUserService userService=(IUserService) Handler.blind(new UserService());
       userService.insert();
    }
}

2.Cglib方式
原理:通过字节码技术,创建一个目标类的子类,作为代理对象,子啊子类中拦截目标类中的方法,对方法做一个加强处理。
创建目标类

public class UserService implements IUserService{

    @Override
    public void insert() {
        System.out.println("添加用户");
    }
}

导入jar包


  cglib
  cglib
  3.2.4

创建一个代理类生成器

package com.test.cglibProxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import sun.reflect.MethodAccessor;

import java.lang.reflect.Method;
import java.util.Date;

//代理对象生成器
public class CglibProxy implements MethodInterceptor {
//创建目标对象的代理对象 并且拦截目标对象中的方法 使之执行代理对象的方法
    Enhancer enhancer = new Enhancer();

    public Object getProxy(Class clazz){
//        设置目标对象的字节码文件 为代理对象的父类
        enhancer.setSuperclass(clazz);
//        设置回调函数 目的使调用intercept()方法
        enhancer.setCallback(this);
//        根据传递过去的参数,创建一个代理对象
        return enhancer.create();
    }


//重写 拦截了目标对象的方法 所做的事情
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("方法执行前:"+new Date());
        Object result=methodProxy.invokeSuper(o,objects);
        System.out.println("方法执行后:"+new Date());
        return null;
    }
}

测试

public class TestCglibProxy {
    @Test
    public void test(){
        CglibProxy cglibProxy = new CglibProxy();
       UserService userService=(UserService)cglibProxy.getProxy(UserService.class);
       userService.insert();
    }
}
三、AOP的使用

1.通过配置文件织入
导入jar包


  org.aspectj
  aspectjweaver
  1.8.10


  org.springframework
  spring-aspects
  4.3.18.RELEASE


  org.springframework
  spring-aop
  4.3.18.RELEASE

配置文件


    
    
    
    
    
        
        
        
        
            
            
            
            

            

            

            
        
    

创建一个接口

public interface IUserService {
    public void add();

}

创建目标类

import com.test.service.IUserService;
import org.springframework.stereotype.Service;

@Service
public class UserService implements IUserService {

    @Override
    public void add() {

    }

}

创建代理类

public class MyAdvice {
    public void before(){
        System.out.println("添加在用户之前:");
    }
    //目标方法执行后(不管是出异常还是成功执行)
    public void after(){
        System.out.println("添加在用户之后:");
    }
//环绕通知  ,用这个增强代码替换掉目标代码
    public void around(ProceedingJoinPoint point) throws Throwable {
        System.out.println("执行目标方法之前");
        point.proceed();//放行异常处的方法

    }
//目标方法成功执行后
    public void afterReturning(){
        System.out.println("目标方法成功执行之后");
    }
//目标代码出现异常
    public void afterException(){
        System.out.println("目标方法出现异常之后才执行");
    }
}

测试

public class TestAop {
    @Test
    public void test(){
        ApplicationContext applicationContext =new ClassPathXmlApplicationContext("applicationContext.xml");
        IUserService userService=applicationContext.getBean("userService", IUserService.class);
        userService.add();
    }
}

2、通过注解方式织入
切面类

//切面类
@Aspect
public class MyAdvice {
//    定义切点表达式
    @Pointcut("execution(* com.test.service.impl.*.add())")
    public void pc(){

    }
    @Before("MyAdvice.pc()")
    public void before(){
        System.out.println("添加在用户之前:"+new Date());
    }
    @After("MyAdvice.pc()")
//目标方法执行后(不管是出异常还是成功执行)
    public void after(){
        System.out.println("添加在用户之后:");
    }
    @Around("MyAdvice.pc()")
//环绕通知  ,用这个增强代码替换掉目标代码
    public void around(ProceedingJoinPoint point) throws Throwable {
        System.out.println("执行目标方法之前");
        point.proceed();//放行异常处的方法

    }
    @AfterReturning("MyAdvice.pc()")
//目标方法成功执行后
    public void afterReturning(){
        System.out.println("目标方法成功执行之后");
    }
    @AfterThrowing("MyAdvice.pc()")
//目标代码出现异常
    public void afterException(){
        System.out.println("目标方法出现异常之后才执行");
    }

}

配置文件






    

四、切点表达式

1.切点表达式:对指定的方法进行拦截,并且生成代理表达式

表达式语法:
execution([修饰符] 返回值类型 包名.类名.方法名(参数))
execution(public void com.test.service.impl.UserService())

2、表达式的不同写法
1.匹配指定方法


2、默认public可以省略


3.匹配任何返回值


4.参数列表可以使用*,表示可以是任何的数据类型,但是必须有参数


5.参数列表可以使用…表示有无参数均可,有参数可以是任意类型


6.使用…表示当前包及其子包


7.类名可以使用*号,表示任意类


Spring事务管理 1.什么是事务

是并发控制的单元,是用户定义的一个操作序列,是一个不可分割的工作单位。通过事务,sql可以将逻辑相关的一组操作绑定在一起,以便服务器保持数据的完整性。事务通常是以begin/start transaction开始,以commit或rollback结束。Commit表示提交,即提交事务的所有操作。rollback表示回滚,即事务在运行的过程中发生了某种故障,事务不能继续运行,系统将事务中对数据库的所有已完成的操作全部撤销,滚回到事务开始的状态。

2.事务的特性

ACID

原子性 事务对于其数据的修改,要么全部执行,要么全部不执行一致性 事务在完成时,必须所有的数据都保持一致状态隔离性 一个事务的执行不能被其他事务所影响持久性 一个事务一旦提交,事务的操作便永久的保存在DB中,即使此时在执行回滚操作也不能撤销所做的更改 3.事务的并发问题

脏读 一个事务读取到另一个事务未提交的数据操作结果不可重复读(虚读)一个事务对同一行数据重复读了两次,但是却得到了不同的结果。(如事务A读取某一个数据后,事务B对其做了修改,当事务A再读该数据的时候就会得到与前一次不同的值)幻读 事务在操作过程中进行两次查询,第二次查询的结果包含第一次查询中未出现的数据或者缺少了第一次查询中出现的数据,这是因为在两次查询过程中有另一个事务插入数据造成的 4.事务的隔离级别

读未提交 最低级别,以上情况均无法保证读已提交(只允许读已提交的事务) 可避免脏读的发生可重复读(保证两次读取的数据一样,即把所要读的记录锁住,不允许修改)可避免脏读、不可重复读的发生,不可避免幻读串行化读Serializable(锁住整张表,添加删除都不允许) 事务只能一个一个的执行,避免脏读、不可重复读、幻读。
5.事务的传播行为
事务方法被另一个事务方法调用时,必须指定事务是如何传播的。
1.PROPALGATION_REQUIRED 表示当前方法必须运行在事务中,如果当前事务存在,方法会在改事务中运行,否则,会启动一个新事务
2.PROPALGATION_SUPPORTS
表示当前方法不需要事务上下文,但是如果存在当前事务的话,那么该方法会在这个事务中运行
3.PROPALGATION_MANDATOY 表示当前方法必须在事务中运行,如果当前事务不存在,则会抛出一个异常
4.PROPALGATION_REQUIRED_NEW
表示当前方法必须运行在它自己的事务中,一个新的事务将被启动。如果存在当前事务,在该方法执行期间,当前事务会被挂起。
5.PROPALGATION_NOT_SUPPORTED
表示该方法不应该运行在事务中。如果存在当前事务,在该方法运行期间,当前事务将被挂起。
6.PROPALGATION_NEVER
表示当前方法不应该运行在事务上下文。如果当前正有一个事务在运行,则会抛出异常
7.PROPALGATION_NESTED
表示如果当前已经存在一个事务,那么该方法会嵌套在事务中运行。嵌套的事务可独立于当前事务进行单独的提交或回滚,如果当前事务不存在,那么其行为与PROPALGATION_REQUIRED 一样 5、Spring中事务的三种实现方式

1.编程式声明管理(一般不用
2.声明式事务管理
2.1基于TransactionProxyFactoryBean的声明式事务管理
(1)、创建异常类

public class MyException extends Exception{
    public MyException() {
    }

    public MyException(String message) {
        super(message);
    }
}

(2)、在service的中的转账方法中模拟出异常效果

@Override
public void transfer(int from, int to, float money) throws Exception {
    cardInfoDao.decrease(from,money);
        if(true)
            throw new Exception("转账异常");//Exception 所有异常的父类
    cardInfoDao.increase(to,money);
}

(3)、在配置文件中创建事务对象及其代理对象



        
        
        
                
                        
                       ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-MyException
                
        

(4)、测试

@Test
public void test(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
   ICardInfoService iCardInfoService= applicationContext.getBean("cardInfoServiceProxy",ICardInfoService.class);
    try {
        iCardInfoService.transfer(1,2,500);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

2.1基于@Transactional注解的声明式事务管理
(1)、修改配置文件



(2)、在service层转账方法中添加注解

    @Override
//    通过注解的方法 生命事务方法  隔离级别 传播行为 回滚条件
    @Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED,rollbackFor = MyException.class)
    public void transfer(int from, int to, float money) throws Exception {
        cardInfoDao.decrease(from,money);
            if(true)
                throw new Exception("转账异常");//Exception 所有异常的父类
        cardInfoDao.increase(to,money);
    }
}

3.基于AOP的事务管理



        
        
        
        

        
                
                
                
                
        

        
        
                
        
        
        
                
        
        
        
                
                        
                
        



        
                
                
                
                
        
        
       



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/754213.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号