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

Spring框架总结

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

Spring框架总结

学习Spring的整体脉络:
  1、IOC控制反转和依赖注入(XML配置和注解)
  2、AOP面向切面编程
  3、Spring使用JDBC
  4、Spring的声明式事务控制

目录
  • 前言
  • 一、XML配置
  • 二、Spring的JDBC
  • 三、注解开发
  • 四、Spring集成Junit
  • 五、SpringAOP
    • 1、JDK动态代理技术
    • 2、cglib动态代理技术
    • 3、AOP的相关概念
    • 4、XML配置AOP详解
    • 5、注解配置AOP详解
  • 六、Spring的事务控制
  • 结语


前言

Spring的简单介绍

Spring是轻量级的开源框架,以IOC和AOP为内核

Spring的优势(了解):
  1、方便解藕,简化开发
  2、AOP编程支持
  3、声明式事务支持
  4、方便程序测试
  5、方便集成各种优秀的框架

什么是IOC

IOC是指控制反转,是将对象的创建控制权交给Spring容器处理,而不是直接创建,实现IOC的方式有两种,一种是通过配置文件进行注入,另一种是通过注解的方式进行注入。

什么是AOP

AOP指的是面向切面编程,底层使用的是动态代理。Spring的AOP由JDK动态代理(针对接口)和cglib动态代理(针对类)这两个实现

pom.xml文件



    4.0.0

    org.example
    Spring
    1.0-SNAPSHOT
    
        
            org.springframework
            spring-context
            5.0.5.RELEASE
        
        
            org.springframework
            spring-jdbc
            5.0.5.RELEASE
        
        
        
            c3p0
            c3p0
            0.9.1.2
        
        
        
            com.alibaba
            druid
            1.1.10
        
        
        
            mysql
            mysql-connector-java
            5.1.38
        
        
        
            junit
            junit
            4.12
        
        
        
            org.springframework
            spring-test
            5.0.15.RELEASE
        
        
        
            org.aspectj
            aspectjweaver
            1.9.6
        
        
        
            org.junit.jupiter
            junit-jupiter
            RELEASE
            compile
        
        
        
            org.springframework
            spring-tx
            5.3.11
        
    

一、XML配置

首先,我们先新建一个配置文件,名字可以随便取,但为了方便后面的阅读,建议名字和我一样:applicationContext.xml
创建的位置在resources目录下

下面我先把约定的俗称列出,把下面内容复制到你的文件内容里,之后的内容都会用到!





如图:

接下来进入正题:
上面我们提到IOC是将类的创建交给容器,以下我们通过XML配置的方式使用,首先是定义一个实体类,然后在xml文件定义bean标签,然后填写对应的属性值

实体类:

//在com.entry包下新建一个实体类
package com.entry;
//新建实体类,类名为User
public class User {
	//设置属性
    private String name;
    //设置map域的属性
    private Map map;
    //设置list域的属性
    private List list;
    //设置数组域的属性
    private String array[]=new String[10];
    //设置Set无序集合的属性
    private Set set;
    //有参和无参构造
    public User() {}
    public User(String name, String password, Map map, List list) {
        this.name = name;
        this.password = password;
        this.map = map;
        this.list = list;
    }
	//设置所有属性的get和set方法
	   public String[] getArray() {
        return array;
    }
    public void setArray(String[] array) {
        this.array = array;
    }
    public Set getSet() {
        return set;
    }
    public void setSet(Set set) {
        this.set = set;
    }
    //设置构造函数
    public List getList() {
        return list;
    }
    public void setList(List list) {
        this.list = list;
    }
    public String getName() {
        return name;
    }
    public Map getMap() {
        return map;
    }
    public void setMap(Map map) {
        this.map = map;
    }
    public void setName(String name) {
        this.name = name;
    }
}

applicationContext.xml配置文件


	
    
    	
        
        
        
            
                
            
        
        
        
            
                111
                222
            
        
                
        
            
                1
                2
            
        
        
        
            
                1
                2
            
        
 

 
        
        
        
            
                111
                222
            
        
        
        
            
                
            
        
 

测试:

import com.entry.User;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserDemo {
    @Test
    public void test(){
    	//获取上下文
        ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = (User) app.getBean("user");
        System.out.println(user.getName());
    }
}

对相关标签的介绍

标签作用
用于定义一个类
属性标识
标识list的属性
属性值
标识map的属性
map中的键值对标识
构造函数标签标识
导入其他的Spring的分文件

属性的介绍

标签属性作用
id属性在容器中Bean实例的唯一标识,不允许重复
class属性要实例化的Bean的全限定名
scope属性Bean的作用范围,常用的是Singleton(默认)和prototype
name属性属性名称
value属性属性值
ref属性引用外部bean,类型需要跟属性名name保持一致,否则无法引用
二、Spring的JDBC

步骤:

1、导入mysql驱动的坐标,和数据池坐标,如果已经导入,则不需要导入


    c3p0
    c3p0
    0.9.1.2



    com.alibaba
    druid
    1.1.10



    mysql
    mysql-connector-java
    5.1.38

2、方式一:直接使用

@Test
public void test() throws PropertyVetoException, SQLException {
	//C3P0的连接池
    ComboPooledDataSource dataSource=new ComboPooledDataSource();
    //给连接池赋值
    dataSource.setDriverClass("com.mysql.jdbc.Driver");
    dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/数据库名");
    dataSource.setUser("数据库用户名");
    dataSource.setPassword("数据库用户密码");
    //获取连接
    Connection connection = dataSource.getConnection();
    //打印测试
    System.out.println(connection);
    //关闭连接
    connection.close();
}

3、方式二:使用xml直接配置



    
    
    
    

4、方式三:使用xml加外部文件配置

外部文件:jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
#端口号默认是3306
jdbc.url=jdbc:mysql://localhost:端口号/数据库名称
jdbc.user=数据库用户名
jdbc.password=数据库密码

xml配置





    
    
    
    

 

   

具体使用

@Test
//测试Spring容器产生数据源对象
public void test4() throws Exception {
    //加载指定的xml文件
    ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
    //获取数据源对象
    DataSource dataSource = app.getBean(DataSource.class);
    //获取连接
    Connection connection = dataSource.getConnection();
    System.out.println(connection);
    //关闭连接
    connection.close();
}

5、方式四:使用注解配置+外部文件配置

外部文件:jdbc.properties

#数据库驱动
jdbc.driver=com.mysql.jdbc.Driver
#端口号默认是3306
jdbc.url=jdbc:mysql://localhost:端口号/数据库名称
jdbc.user=数据库用户名
jdbc.password=数据库密码

配置文件类

//配置文件核心注解
@Configuration
// 
//    
@ComponentScan("com")
//
//
@PropertySource("classpath:jdbc.properties")
public class SpringConfig {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.user}")
    private String user;
    @Value("${jdbc.password}")
    private String password;
    @Bean("dataSource")
    public DataSource getDataSource() throws Exception {
        ComboPooledDataSource dataSource=new ComboPooledDataSource();
        dataSource.setDriverClass(driver);
        dataSource.setJdbcUrl(url);
        dataSource.setUser(user);
        dataSource.setPassword(password);
        return dataSource;
    }
}

具体使用

 @Test
    public void test5() throws SQLException {
        ApplicationContext app=new AnnotationConfigApplicationContext(SpringConfig.class);
        DataSource dataSource = app.getBean(DataSource.class);
        Connection connection = dataSource.getConnection();
        //打印连接
        System.out.println(connection);
        connection.close();
    }
三、注解开发

原始注解:主要替代配置
其中@Controller、@Service、@Repository这三个标签的作用和@Component一样,只是为了赋予了不同的语义化概念。

注解说明
@Component使用在类上用于实例化Bean
@Controller使用在Web层类上用于实例化Bean
@Service使用在service层类上用于实例化Bean
@Repository使用在dao层类上用于实例化Bean
@Autowired使用在字段上用于根据类型依赖注入
@Qualifier结合@Autowired一起使用,用于根据名称进行依赖注入,按照id值从容器中进行匹配的
@Resource相当于@Autowired+@Qualifier,按照名称进行注入
@Value注入普通属性
@Scope标注Bean的作用范围
@PostConstruct使用在方法上标注该方法是Bean的初始化方法
@PreDestroy使用在方法上标注该方法是Bean的销毁方法

步骤1:写入注解
步骤2:注册组件,这样注解才能生效
也就是在xml配置文件添加以下代码


如下代码:

新注解

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

1、导入spring集成Junit的坐标


    junit
    junit
    4.12



    org.springframework
    spring-test
    5.0.15.RELEASE

2、使用@Runwith注解替换原来的运行期

@RunWith(SpringJUnit4ClassRunner.class)

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


@ContextConfiguration(classes = {SpringConfig.class})

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

//使用Autowired注解将UserService注入
@Autowired
private UserService userService;

5、创建测试方法进行测试

//编写测试类,调用对象,查看是否可用
@Test
public void test(){
    userService.save();
}
五、SpringAOP

1、AOP的作用及其优势

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

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

2、AOP的底层实现

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

3、AOP的具体实现

  • JDK代理:基于接口的动态代理技术
  • cglib代理:基于父类的动态代理技术
1、JDK动态代理技术


jdk代理主要通过反射的方式进行代理,JDK代理本身就继承了Proxy类,由于Java不支持多继承,所以不支持对类的代理,只支持对接口的代理。
具体案例如下:

//接口1
interface IBoard {
	void draw();
}
//接口2
interface IComputer {
	void open();
	void complete();
}
//接口1的实现类
class Board implements IBoard{
	@Override
	public void draw() {
		System.out.println("被代理类画画操作执行");
	}
}
//接口2的实现类
class Computer implements IComputer{
	@Override
	public void open() {
		System.out.println("电脑正在启动....");	
	}
	@Override
	public void complete() {
		System.out.println("电脑启动完成");
	}
}
//代理类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

class JDKProxy {
	//设置被代理对象
	private Object target;
	//通过构造函数设置被代理对象
	public JDKProxy(Object target) {
	 this.target=target;
	}
	//被代理对象生成
	public Object getProxyInstance() {
		//返回一个JDK代理类对象
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),new InvocationHandler() {

			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				System.out.println("=================");
				System.out.println("代理开始");
				Object object=method.invoke(target, args);
				System.out.println("被代理的方法名:"+method.getName());
				if("open"==method.getName()) {
					Method complete=target.getClass().getMethod("complete");
					if(null!=complete){
						System.out.println("complete方法被代理对象自动调用");
						Thread.sleep(1000);
						complete.invoke(target, args);
					}
				}
				System.out.println("代理结束");
				System.out.println("=================");
				System.out.println();
				return object;
			}
		});
	}
}
//使用者
public class Client {
	public static void main(String[] args) {
		//代理画板对象
		JDKProxy board=new JDKProxy(new Board());
		IBoard iBoard=(IBoard)board.getProxyInstance();
		//调用画板的draw()方法
		iBoard.draw();
		//代理电脑对象
		JDKProxy computer=new JDKProxy(new Computer());
		IComputer iComputer=(IComputer) computer.getProxyInstance();
		//这里只调用了open()方法,但是complete会被代理对象自动调用
		iComputer.open();
	}
}
2、cglib动态代理技术

实现代理的关键:

  • 创建工具类Enhancer
  • 设置它的父类,会在虚拟机生成一个父类
  • 设置回调函数
  • 创建子类对象,作为代理对象


我们知道,使用Jdk代理的不足之处是不能对类进行代理,而Cglib代理刚好解决了这个问题。
Cglib可以对无接口的类进行代理,需要实现MethodInterceptor接口

具体案例:

//没有实现接口的类1
class Board{
	public void draw() {
		System.out.println("被代理类画画操作执行");
	}
}
//没有实现接口的类2
class Computer{
	public void open() {
		System.out.println("电脑正在启动....");
	}
	public void complete() {
		System.out.println("电脑启动完成");	
	}
}
//Cglib代理
import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
//实现MethodInterceptor接口,重写intercept方法(实现代理功能)
class CglibProxy implements MethodInterceptor{
	//设置被代理类
	public Object target;
	//通过构造函数进行设置
	public CglibProxy(Object target) {
		this.target=target;
	}
	public Object getProxyInstance() {
		//创建工具类
		Enhancer e=new Enhancer();
		//设置父类
		e.setSuperclass(target.getClass());
		//设置回调函数
		e.setCallback(this);
		//创建子类对象,作为代理对象
		return e.create();
	}
	@Override
	public Object intercept(Object arg0, Method method, Object[] args, MethodProxy arg3) throws Throwable {
		System.out.println("===============");
		//代理模式底层使用反射
		System.out.println("Cglib代理模式开始");
		//invoke激活,和jdk代理功能类似
		Object object=method.invoke(target, args);
		System.out.println("被代理的方法名:"+method.getName());
		//在代理类实现自己的功能
		if("open"==method.getName()) {
			Method complete=target.getClass().getMethod("complete");
			if(null!=complete){
				System.out.println("complete方法被代理对象自动调用");
				Thread.sleep(1000);
				complete.invoke(target, args);
			}
		}
		System.out.println("代理结束");
		System.out.println("=================");
		System.out.println();
		return object;
	}
}

另一种方式:不需要类去实现MethodInterceptor接口,是在回调函数的实现这个接口

//没有实现接口的类1
class Board{
	public void draw() {
		System.out.println("被代理类画画操作执行");
	}
}
//没有实现接口的类2
class Computer{
	public void open() {
		System.out.println("电脑正在启动....");
	}
	public void complete() {
		System.out.println("电脑启动完成");	
	}
}
//Cglib代理
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
//实现MethodInterceptor接口,重写intercept方法(实现代理功能)
class CglibProxy2{
	//设置被代理类
	public Object target;
	//通过构造函数进行设置
	public CglibProxy2(Object target) {
		this.target=target;
	}
	
	public Object getProxyInstance() {
		//创建工具类
		Enhancer e=new Enhancer();
		//设置父类
		e.setSuperclass(target.getClass());
		//设置回调函数
		e.setCallback(new MethodInterceptor() {

			@Override
			public Object intercept(Object arg0, Method method, Object[] args, MethodProxy proxy) throws Throwable {
				System.out.println("===============");
				//代理模式底层使用反射
				System.out.println("Cglib代理模式开始");
				//invoke激活,和jdk代理功能类似
				Object object=method.invoke(target, args);
				System.out.println("被代理的方法名:"+method.getName());
				//在代理类实现自己的功能
				if("open"==method.getName()) {
					Method complete=target.getClass().getMethod("complete");
					if(null!=complete){
						System.out.println("complete方法被代理对象自动调用");
						Thread.sleep(1000);
						complete.invoke(target, args);
					}
				}
				System.out.println("代理结束");
				System.out.println("=================");
				System.out.println();
				return object;
			}
		});
		//创建子类对象,作为代理对象
		return e.create();
	}
}

想看更多的设计模式请进:Java设计模式总结篇

3、AOP的相关概念

常用的术语如下:

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

1、切入表达式的写法

表达式语法:

execution([修饰符] 返回值类型 包名.类名.方法名(参数类型))
  • 访问修饰符可以省略
  • 返回值类型、包名、类名、方法名可以使用星号*代表任意
  • 包名与类名之间一个点.代表当前包下的类,两个点..表示当前包及其子包下的类
  • 参数列表可以使用两个点..表示任意个数、任意类型的参数列表
//method()指方法(切点),Target指类名(切面),com.aop值包名
execution(public void com.aop.Target.method())
//方式二,采用*号和一个.
execution(* com.aop.*.*())
//方式三,采用*号和一个.和两个. 比较常用
execution(* com..*.*(..))
//方式四 基本不会用上
execution(* *..*.(..))

2、通知种类

通知的配置语法:


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

代码展示:
在com.aop包中新建一个MyAspect类,Target类和TargetInterface接口

package com.aop;

//切面
public class MyAspect {
	//切点
    public void before(){
        System.out.println("前置增强");
    }
    public void afterRetuning(){
        System.out.println("后置增强");
    }
}
//接口
interface TargetInterface {
    public void save();
}
//目标方法
public class Target implements TargetInterface{
    public void save(){
        System.out.println("Save.........");
    }
}

在xml文件进行配置AOP






	
	
		
    	
        
    

使用Junit测试看看

import com.aop.TargetInterface;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
    @Autowired
   private TargetInterface target;
   @Test
    public void test(){
       target.save();
   }
}
5、注解配置AOP详解

注解AOP开发步骤:

  • 使用@Aspect标注切面类
  • 使用@通知注解标注通知方法
  • 在配置文件中配置aop自动代理让注解生效

通知注解的类型:

名称标签说明
前置通知@Before用于配置前置通知,指定增强方法在切入点方法之前执行
后置通知@AfterReturning用于配置后置通知,指定增强方法在切入点方法之后执行
环绕通知@Around用于配置环绕通知,指定增强方法在切入点方法之前和之后执行
异常抛出通知@AfterThrowing用于配置异常抛出通知,指定增强方法在出现异常时执行
最终通知@After用于配置最终通知,无论增强方法执行是否有异常都会执行
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component("myAspect")
@Aspect//告诉Spring容器Myspect是一个切面
public class MyAspect {
    @Before("execution(* com..*.*(..))")
    public void before(){
        System.out.println("前置增强");
    }
    @AfterReturning
    public void afterRetuning(){
        System.out.println("后置增强");
    }
}
六、Spring的事务控制

知识要点:

平台事务管理器配置

事务通知配置

事务aop的织入配置

基于xml的声明式事务控制

通过转账业务进行测试

xml配置文件




    
    
    
    
        
        
        
        
    
    
    
        
    
    
        
    

    
    
        
    
    
    
        
    
    
    
        
            
            
        
    
    
    
        
    

实体类

public class Account {
    private String name;
    private double money;
    //设置方法
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getMoney() {
        return money;
    }
    public void setMoney(double money) {
        this.money = money;
    }
}

Service层

转账业务接口

public interface AccountService {
    public void transfer(String outMan,String inMan,double money);
}

Service的实现类


public class AccountServiceImpl implements AccountService {
    private AccountDao accountDao;

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }
    @Transactional
    public void transfer(String outMan, String inMan, double money) {
        //支出人,金额
        accountDao.out(outMan,money);
        //收款人,金额
        accountDao.in(inMan,money);
    }
}

Dao层
转账数据访问层接口

public interface AccountDao {
    public void out(String outMan,double money);
    public void in(String inMan,double money);
}

Dao的实现类

public class AccountDaoImpl implements AccountDao {
    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public void out(String outMan, double money) {
        String sql="select money from account where name='"+outMan+"'";

        Integer sql_money = jdbcTemplate.queryForObject(sql, Integer.class);
        if (sql_money>=money){
            jdbcTemplate.update("update account set money=money-? where name=? ",money,outMan);
        }else {
            System.out.println("对不起!"+outMan+"。您的的金额不足,无法进行交易!");
            //退出程序
            System.exit(0);
        }
    }
    //存钱
    public void in(String inMan, double money) {
        jdbcTemplate.update("update account set money=money+? where name=?",money,inMan);
    }
}

Controller层

public class AccountController {
    public static void main(String[] args) {
        ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
        AccountService accountService = app.getBean(AccountService.class);
        accountService.transfer("zhangsan","lisi",50);
    }
}

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

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

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

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

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

实现步骤如下:

修改xml配置文件(applicationContext)




    
    
    
    
    
    
        
        
        
        
    
    
        
    
    
    
        
    
	
    

修改Dao层的类(AccountDaoImpl 类)

@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;
	//取钱
    public void out(String outMan, double money) {
    	//定义sql语句
        String sql="select money from account where name='"+outMan+"'";
		//执行sql语句
        Integer sql_money = jdbcTemplate.queryForObject(sql, Integer.class);
        //逻辑判断
        if (sql_money>=money){
            jdbcTemplate.update("update account set money=money-? where name=? ",money,outMan);
        }else {
            System.out.println("对不起!"+outMan+"。您的的金额不足,无法进行交易!");
            //退出程序
            System.exit(0);
        }
    }
    //存钱
    public void in(String inMan, double money) {
        jdbcTemplate.update("update account set money=money+? where name=?",money,inMan);
    }
}

修改Service的类(AccountServiceImpl 类)

@Service("accountService")
public class AccountServiceImpl implements AccountService {
    @Autowired
    private AccountDao accountDao;
    //可以加参数,可以把该注解放到类外头,表示统一的数据库参数配置
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public void transfer(String outMan, String inMan, double money) {
        //支出人,金额
        accountDao.out(outMan,money);
        //收款人,金额
        accountDao.in(inMan,money);
    }
}

事务控制小结

使用xml的方式
  首先需要配置通知事务的增强,然后配置事务织入,如:

    
        
            
            
        
    
    
    
        
    

使用注解的方式更加简单
  只需要在需要声明事务的地方添加@Transactional注解,并配置相关的参数和在xml配置文件中要开启事务的注解驱动,开启组件扫描,
xml的配置,再加上@Transactional

 	
    
	
    
结语

本篇文章是学习笔记,记录下来的方便之后的复习,如果有问题的请指出,不吝赐教。

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

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

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