- Spring是轻量级的开源的JavaEE框架。
- Spring可以解决企业应用开发的复杂性。
- Spring有两个核心部分:IOC和AOP。
- IOC:控制反转,把创建对象过程交给Spring进行管理。
- AOP:面向切面编程,不修改源代码的情况下进行功能增强。
- Spring特点
- 方面解耦,简化开发
- AOP编程支持
- 方便程序的测试
- 可以方便和其他框架进行整合
- 方便进行事务操作
- 降低API开发难度
- 什么是IOC:控制反转,把对象创建和对象之间的调用过程交给Spring进行管理。
- 使用IOC的目的:为了降低耦合度。
- xml解析、工厂模式、反射
- IOC思想基于IOC容器完成,IOC容器底层就是对象工厂。
- Spring提供IOC容器实现的两种方式(两个接口)
- BeanFactory:IOC容器基本实现,是Spring内部的使用接口,不提供开发人员进行使用
- ApplicationContext:接口的子接口,提供更多更强大的功能,一般由开发人员进行使用
- 区别:BeanFactory在加载配置文件时不会创建对象,在获取对象(使用)才去创建对象;ApplicationContext在加载配置文件时就会把配置文件中的对象进行创建。
- BeanFactory接口主要实现类
- FileSystemXmlApplicationContext:配置文件需要用系统路径(绝对路径)
- ClassPathXmlApplicationContext:配置文件使用相对路径
-
什么是Bean管理?
- Spring创建对象
- Spring注入属性
-
Bean管理操作有两种方式
- 基于xml配置文件方式实现
- 基于注解方式实现
-
基于xml方式
-
创建对象
在spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建
在bean标签中有很多属性,常用的属性有:id(唯一标识);class(类全路径或包类路径);
创建对象时,默认也是执行无参构造方法
-
注入属性
- DI:依赖注入,就是注入属性。DI是IOC的一种具体实现;注入属性必须在创建完对象的基础上。
-
两种注入方式:set方法和有参构造方法。
-
第一种:set方法注入
- 创建类,定义属性和对应的set方法
public class Book{ private String bname; private String bauthor; public void setBname(String bname){ this.bname = bname; } public void setBauthor(String bauthor){ this.bauthor = bauthor; } }- 在Spring配置文件中配置对象创建,配置属性注入
-
第二种:基于有参构造方法注入
-
创建类,定义属性,创建属性对应有参构造方法
-
public class Orders{ private String oname; private String address; public Orders(String oname, String address){ this.oname = oname; this.address = address; } public void orderTest(){ System.out.println(oname+"::"+address) } } -
在Spring配置文件中进行配置
- 测试
@Test public void testOrders(){ //1、加载spring配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml"); //2、获取配置创建的对象 Orders orders = context.getBean("orders",Orders.class); System.out.println(orders); orders.orderest(); } -
-
-
xml注入其他类型属性
-
字面量:是用于源代码中一个固定值的表示法
- null值
- 属性值包含特殊符号
-
注入属性-外部Bean
- 创建两个类service类和dao类
- 在service中调用dao里面的方法
public class UserService { //创建UserDao类型属性,生成set方法 private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void add(){ System.out.println("service add....."); userDao.update(); } } public class UserDaoImpl implements UserDao{ @Override public void update() { System.out.println("dao update...."); } } public class Test_02 { @Test public void test(){ //使用ApplicationContext加载配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); //创建service对象 UserService userService = context.getBean("userService", UserService.class); //调用User中的方法 userService.add(); } } -
注入属性-内部Bean和级联赋值
- 内部Bean
//部门类 public class Dept { private String dname; public void setDname(String dname) { this.dname = dname; } @Override public String toString() { return "Dept{" + "dname='" + dname + ''' + '}'; } } //员工类 public class Emp { private String ename; private String gender; private Dept dept; //员工所属部门 public void setEname(String ename) { this.ename = ename; } public void setGender(String gender) { this.gender = gender; } public void setDept(Dept dept) { this.dept = dept; } }//测试 @Test public void test2(){ //使用ApplicationContext加载配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); //创建service对象 Emp emp = context.getBean("emp", Emp.class); //调用User中的方法 emp.print(); } //输出结果 //张曼玉 女 Dept{dname='演艺部'}- 级联赋值
-
-
xml注入集合属性
java面向对象程序设计 数据库设计 Spring5 张三 李四 王麻子 嘿嘿 哈哈 呵呵 //学生类 public class Stu { private String[] courses; private Listlist; private Map maps; private Set sets; public void setCourses(String[] courses) { this.courses = courses; } public void setList(List list) { this.list = list; } public void setMaps(Map maps) { this.maps = maps; } public void setSets(Set sets) { this.sets = sets; } @Override public String toString() { return "Stu{" + "courses=" + Arrays.toString(courses) + ", list=" + list + ", maps=" + maps + ", sets=" + sets + '}'; } } //测试 public class Test { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); Stu stu = context.getBean("stu", Stu.class); System.out.println(stu); } } //输出结果 //Stu{courses=[java面向对象程序设计, 数据库设计, Spring5], list=[张三, 李四, 王麻子], maps={JAVA=java, PHP=php}, sets=[嘿嘿, 哈哈, 呵呵]} -
在集合里面设置对象类型值
-
把集合注入部分提取出来
-
-
Bean管理(FactoryBean)
- Spring有两种Bean,一种普通Bean,另一种工厂bean(FactoryBean)
- 普通Bean:配置文件中定义什么类型就返回什么类型
- 工厂Bean:配置文件中定义类型和返回类型可以不一致
public class MyBean implements FactoryBean
{ @Override public Stu getObject() throws Exception { Stu stu = new Stu(); stu.setCourses(new String[]{"java","spring5"}); return stu; } @Override public Class> getObjectType() { return null; } @Override public boolean isSingleton() { return false; } } -
Bean的作用域
- 在spring里面,可以设置bean实例是单实例还是多实例(使用scope:singleton、prototype、request、session)。singleton和prototype的区别:1、singleton为单实例,加载配置文件时就会创建对象。2、prototype为多实例,加载的时候并不创建对象,而是在调用getBean()方法时创建多实例对象。
- 在spring里面,默认情况下,bean是单实例对象
//地址相同,说明stu1和stu2是同一个实例化对象 ApplicationContext context = new ClassPathXmlApplicationContext("spring-config2.xml"); Stu stu1 = context.getBean("stu", Stu.class); Stu stu2 = context.getBean("stu", Stu.class); System.out.println(stu1); System.out.println(stu2); //输出结果 //com.atguigu.spring5.collectiontype.Stu@1e66f1f5 //com.atguigu.spring5.collectiontype.Stu@1e66f1f5 -
Bean管理的生命周期:bean从创建到销毁的过程
- 创建bean实例——>为bean的属性设置值和对其他bean引用(set方法)——>调用bean的初始化的方法(需要进行配置)——>使用——>当容器关闭时,调用bean的销毁方法(需要进行配置)
- 添加后置处理器后变为7步:创建bean实例——>为bean的属性设置值和对其他bean引用(set方法)——>初始化前执行的方法——>调用bean的初始化的方法(需要进行配置)——>初始化后执行的方法——>使用——>当容器关闭时,调用bean的销毁方法(需要进行配置)
-
xml自动装配(很少使用)
- 根据指定装配规则(属性名或者属性类型),Spring自动将匹配的属性值注入
-
基于注解方式
-
什么是注解?注解是代码特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值…);注解可以作用在类、方法、属性上面。使用注解的目的:简化xml配置。
-
spring针对Bean管理中创建对象提供注解
- @Component
- @Service
- @controller
- @Repository
以上四个注解功能都是一样的,都可以用来创建bean实例。
//UserService类 //在注解里面value属性值可以不写,默认值是类名称,首字母小写 @Component(value="userService") //相当于
public class UserService { public void add(){ System.out.println("service add..."); } } //测试类 public class TestDemo { @Test public void testService(){ //加载配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("spring-config2.xml"); UserService userService = context.getBean("userService", UserService.class); userService.add(); System.out.println(userService); } } -
基于注解方式实现属性注入
- @AutoWired:根据属性类型自动装配
- @Qualifier:根据属性名称进行注入,和@AutoWired一起使用
- @Resource:可以根据类型注入,也可以根据名称注入
- @Value:注入普通类型属性
-
完全注解开发
- 创建配置类,替代xml配置文件
@Configuration //将当前类作为配置类,替代xml文件 @ComponentScan(basePackages = "com.atguigu") //开启组件扫描 public class SpringConfig { }- 测试类(与之前有所不同)
public void Test02(){ //加载配置类 AnnotationConfigApplicationContext ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); //创建对象 UserService userService = context.getBean("userService", UserService.class); //调用方法 System.out.println(userService); userService.add(); }
-
- 什么是AOP?面向切面编程,是OOP的一种延续,是软件开发的一个热点。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间耦合度降低,提高程序的可重用性,同时提高开发效率。
-
动态代理
-
有两种情况动态代理:(1)有接口情况,使用JDK动态代理(2)没有接口情况,使用CGLIB动态代理
//JDK动态代理
首先定义一个People接口
package reflect; public interface People { public String work(); }定义一个Teacher类,该类实现People接口
package reflect; public class Teacher implements People{ @Override public String work() { System.out.println("老师教书育人..."); return "教书"; } }现在我们要定义一个代理类的调用处理程序,每个代理类的调用处理程序都必须实现InvocationHandler接口,代理类如下:
package reflect; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class WorkHandler implements InvocationHandler{ //代理类中的真实对象 private Object obj; public WorkHandler() { // TODO Auto-generated constructor stub } //构造函数,给我们的真实对象赋值 public WorkHandler(Object obj) { this.obj = obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //在真实的对象执行之前我们可以添加自己的操作 System.out.println("before invoke。。。"); Object invoke = method.invoke(obj, args); //在真实的对象执行之后我们可以添加自己的操作 System.out.println("after invoke。。。"); return invoke; } }接下来我们看下客户端类
package reflect; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) { //要代理的真实对象 People people = new Teacher(); //代理对象的调用处理程序,我们将要代理的真实对象传入代理对象的调用处理的构造函数中,最终代理对象的调用处理程序会调用真实对象的方法 InvocationHandler handler = new WorkHandler(people); People proxy = (People)Proxy.newProxyInstance(handler.getClass().getClassLoader(), people.getClass().getInterfaces(), handler); //System.out.println(proxy.toString()); System.out.println(proxy.work()); } }看下输出结果:
before invoke。。。 老师教书育人... after invoke。。。 教书
-
- Advice (增强/通知)实际增强的逻辑部分成为通知(增强);通知分为(前置通知@Before、后置通知@AfterReturning、环绕通知@Around、异常通知@AferThrowing、最终通知@After)。如果有异常,AfterReturning就不执行;AfterReturning在返回值之后执行。
- JoinPoint (连接点) 表示允许使用增强的地方。基本每个方法的前、后或异常等都是连接点。
- Pointcut (切入点) 表示实际增强的方法。
- Aspect (切面) 表示扩展功能的过程。
- Introduction( 引入) 表示向现有的类中添加新方法、新属性。
- Target (目标对象) 表示被增强的对象。
- Proxy (代理) 表示实现AOP的机制。
- Weaving (织入) 表示把增强应用到目标对象的过程。
-
切入点表达式
语法结构:execution([权限修饰符] [返回类型] [类全路径] [方法名称] ([参数列表]))
举例1:对com.atguigu.dao.BookDao类里面的add进行增强 execution(* int com.atguigu.dao.BookDao.add(..)) 举例2:对com.atguigu.dao.BookDao类里面的所有方法进行增强 execution(* com.atguiug.dao.BookDao.*(..)) 举例3:对com.atguigu.dao包里面所有类,类里面所有方法进行增强 execution(* com.atguigu.dao.*.*(..))
-
AspectJ注解
//1.创建类,在类里面定义方法 public class User { public void add(){ System.out.println("add ...."); } } //2、编写增强逻辑 @Component @Aspect public class UserProxy { //前置通知 @Before(value = "execution(* com.atguigu.spring5.aop.User.add(..))") //增强add()方法 public void before(){ System.out.println("before ..."); } //后置通知 @AfterReturning(value = "execution(* com.atguigu.spring5.aop.User.add(..))") public void afterReturning(){ System.out.println("afterReturning..."); } //环绕通知--------需要ProceedingJoinPoint类型参数 @Around(value = "execution(* com.atguigu.spring5.aop.User.add(..))") public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { //环绕之前 System.out.println("环绕之前..."); //被增强的方法 proceedingJoinPoint.proceed(); //环绕之后 System.out.println("环绕之后..."); } //最终通知 @After(value = "execution(* com.atguigu.spring5.aop.User.add(..))") public void after(){ System.out.println("after..."); } //异常通知 @AfterThrowing(value = "execution(* com.atguigu.spring5.aop.User.add(..))") public void afterThrowing(){ System.out.println("afterThrowing..."); } } //3、进行通知的配置测试类
public class TestAop { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); User user = context.getBean("user", User.class); user.add(); } }输出结果
环绕之前... before ... add .... 环绕之后... after... afterReturning...
-
AspectJ配置文件(使用较少)
spring对JDBC进行了封装,JDBCTemplate方便实现对数据库的操作。
2、准备工作-
引入相关jar包
mysql-connector-java-5.1.37-bin.jar (需要与数据库版本相匹配,否则会报错)
spring-jdbc-5.2.3.RELEASE.jar
spring-orm-5.2.3.RELEASE.jar
spring-tx-5.2.3.RELEASE.jar
druid-1.2.8.jar(德鲁伊数据库连接池)
-
在spring配置文件中配置数据库连接池
-
配置jdbcTemplate对象,注入DataSource
-
创建service类,创建dao类,在service中注入到,dao中注入jdbcTemplate
service类
@Service public class BookService { //注入bookdao @Autowired private BookDao bookDao; }BookDao接口
public interface BookDao { }BookDaoImple类实现BookDao
@Repository public class BookDaoImpl implements BookDao{ //注入jdbcTemplate @Autowired private JdbcTemplate jdbcTemplate; }spring相关配置
-
jdbcTemplate操作数据库
-
创建数据库中实体类
public class Book { private int id; private String bookname; private String author; private String publish; private String isbn; private float price; private String bookresume; private String publishdate; public Book(){ super(); } public Book(int id, String bookname, String author, String publish, String isbn, float price, String bookresume, String publishdate) { this.id = id; this.bookname = bookname; this.author = author; this.publish = publish; this.isbn = isbn; this.price = price; this.bookresume = bookresume; this.publishdate = publishdate; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getBookname() { return bookname; } public void setBookname(String bookname) { this.bookname = bookname; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getPublish() { return publish; } public void setPublish(String publish) { this.publish = publish; } public String getIsbn() { return isbn; } public void setIsbn(String isbn) { this.isbn = isbn; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } public String getBookresume() { return bookresume; } public void setBookresume(String bookresume) { this.bookresume = bookresume; } public String getPublishdate() { return publishdate; } public void setPublishdate(String publishdate) { this.publishdate = publishdate; } @Override public String toString() { return "Book{" + "id=" + id + ", bookname='" + bookname + ''' + ", author='" + author + ''' + ", publish='" + publish + ''' + ", isbn='" + isbn + ''' + ", price=" + price + ", bookresume='" + bookresume + ''' + ", publishdate='" + publishdate + ''' + '}'; } } -
编写service和dao
BookService最终实现
@Service public class BookService { //注入bookdao @Autowired private BookDao bookDao; //添加 public void addBook(Book books){ bookDao.add(books); } //修改 public void updateBook(){ bookDao.updateBook(); } //删除 public void deleteBook(int id){ bookDao.deleteBook(id); } //查询单个值 public void findCount(){ bookDao.findCount(); } //查询返回一个对象类型 public Book findBookDetail(int id){ return bookDao.findBookDetail(id); } //查询返回一个集合 public ListfindAllBook(){ return bookDao.findAllBook(); } } BookDao接口
public interface BookDao { //添加 void add(Book book); //查找 void query(Book book); //修改 void updateBook(); //删除 void deleteBook(int id); //查询表记录数 void findCount(); //查询某本书详情,返回该书本对象 Book findBookDetail(int id); ListfindAllBook(); } BookDaoImpl实现类
@Repository public class BookDaoImpl implements BookDao{ //注入jdbcTemplate @Autowired private JdbcTemplate jdbcTemplate; //添加 @Override public void add(Book book) { int id = book.getId(); String bookname = book.getBookname(); String author = book.getAuthor(); String isbn = book.getIsbn(); String publish = book.getPublish(); float price = book.getPrice(); String bookresume = book.getBookresume(); String publishdate = book.getPublishdate(); //创建sql语句 String sql = "insert into books values (?,?,?,?,?,?,?,?)"; int update = jdbcTemplate.update(sql, id, bookname, author, publish, isbn, price, bookresume, publishdate); System.out.println(update); } @Override public void query(Book book) { int id = book.getId(); String bookname = book.getBookname(); String author = book.getAuthor(); String isbn = book.getIsbn(); String publish = book.getPublish(); float price = book.getPrice(); String bookresume = book.getBookresume(); String publishdate = book.getPublishdate(); //创建sql语句 String sql = "selct * from books"; } //修改 @Override public void updateBook() { String sql = "update books set bookname = ? where id = ?"; int update = jdbcTemplate.update(sql, "神雕侠侣", 9); System.out.println("总共"+update+"受影响"); } //删除 @Override public void deleteBook(int id) { String sql = "delete from books where id = ?"; int update = jdbcTemplate.update(sql, 9); System.out.println("共删除"+update+"行记录"); } //查询表记录数 @Override public void findCount() { String sql = "select count(*) from books"; Integer count = jdbcTemplate.queryForObject(sql, Integer.class); System.out.println("books表中共有"+count+"条记录"); } //查询书本详情 @Override public Book findBookDetail(int id) { String sql = "select * from books where id = ?"; Book book = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper(Book.class), id); return book; } //查询Book集合 @Override public List findAllBook() { String sql = "select * from books"; List books = jdbcTemplate.query(sql, new BeanPropertyRowMapper (Book.class)); return books; } } 测试类
import java.util.Iterator; import java.util.List; public class Testjdbc { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); BookService bookService = context.getBean("bookService", BookService.class); //添加元素 Book book1 = new Book(9, "九阴真经", "无名氏", "机械工业出版社", "12345678", 23.6f, "作者很懒,没有简介", "1998-07"); // bookService.addBook(book); //增 // bookService.updateBook(); //改 // bookService.deleteBook(9); //删 // bookService.findCount(); //查 返回单个值 //返回一个book对象 --Book类需要有无参构造方法,否则报错 // Book book2 = bookService.findBookDetail(8); // System.out.println(book2); //返回ListList allBook = bookService.findAllBook(); Iterator iterator = allBook.iterator(); while(iterator.hasNext()) System.out.println(iterator.next()); } } 测试结果
添加:
修改:
删除:
查找:单个返回值
查找:返回book对象
查找:返回集合
-
什么是事务?事务是数据库操作的最基本单元,逻辑上的一组操作,该操作要么都执行,要么不执行。
2、事务的四个特性(ACID)- 原子性:操作要么全部执行,要么都不执行
- 一致性:操作前和操作后的状态保持一致(例如银行转账前和转账后的总钱数是相同的)
- 隔离性:不同事务的操作互不影响
- 持久性:事务提交之后的改变是永久的
-
事务通常添加到Service层
-
spring中有两种方式进行事务管理:编程式事务管理(了解)和声明式事务管理(使用)
- 声明事务管理:基于注解方式(常用)和基于xml配置文件方式
- 声明事务管理底层使用了AOP原理
-
事务操作
-
1、在spring配置文件中配置事务管理器
-
配置开启事务注解
先引入命名空间tx
开启事务注解
在service类上面(或者里面的方法上面)添加事务注解**@Transactional**
如果注解添加在类上面,那么类里面的所有方法都添加事务;如果注解添加到方法上面,那么只有该方法添加事务。
事务注解中的参数设置
1、**propagation:**事务传播行为。多事务方法间直接进行调用,这个过程中事务是如何进行管理的。
spring定义了7种传播行为:
传播属性 描述 REQUIRED 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。 MANDATORY 支持当前事务,如果当前没有事务,就抛出异常。 REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。 NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。 NESTED 支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。 2、**isolation:**事务隔离级别
事务有特性成为隔离性,多事务操作之间不会产生影响。不考虑隔离性产生很多问题
有三个读问题:脏读、不可重复读、虚(幻)读 **脏读(致命问题):**一个未提交事务读取到另一个未提交事务的数据
**不可重复读:**一个未提交事务读取到另一个已提交事务的数据
**虚(幻)读:**一个未提交事务读取到另一个已提交事务添加的数据
解决:通过设置事务隔离级别,解决读问题
脏读 不可重复读 幻读 READ UNCOMMITTED(读未提交) 有 有 有 READ COMMITTED(读已提交) 无 有 有 REPEATABLE READ(可重复读) 无 无 有 SERIALIZABLE(串行化) 无 无 无 3、**timeout:**超时时间
事务需要在一定时间内进行提交,如果不提交进行回滚
默认值是-1 ,设置时间以秒单位进行计算4、**readOnly:**是否只读
读:查询操作,写:添加修改删除操作
readOnly 默认值false,表示可以查询,可以添加修改删除操作
设置readOnly 值是true,设置成true 之后,只能查询5、**rollbackFor:**回滚
设置出现哪些异常进行事务回滚
6、**noRollbackFor:**不回滚
设置出现哪些异常不进行事务回滚
-
xml声明式事务管理
第一步 配置事务管理器
第二步 配置通知
第三步 配置切入点和切面
-
完全注解实现声明式事务管理
第一步 创建配置类,替代xml文件
package com.atguigu.spring5.config; import com.alibaba.druid.pool.DruidDataSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.sql.DataSource; @Configuration //配置类 @ComponentScan(basePackages = "com.atguigu") //组件扫描 @EnableTransactionManagement //开启事务 public class TxConfig { //创建数据库连接池 @Bean public DruidDataSource getDruidDataSource(){ DruidDataSource dataSource = new DruidDataSource(); //德鲁伊连接池 dataSource.setDriverClassName("com.mysql.jdbc.Driver"); //加载驱动 dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/account?characterEncoding=UTF-8"); //url dataSource.setUsername("root"); //用户名 dataSource.setPassword("root"); //密码 return dataSource; } //创建jdbcTemplate对象 @Bean public JdbcTemplate getJdbcTemplate(DataSource dataSource){ //到ioc容器中根据类型找到dataSource JdbcTemplate jdbcTemplate = new JdbcTemplate(); //注入dataSource jdbcTemplate.setDataSource(dataSource); return jdbcTemplate; } //创建事务管理器 @Bean public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource){ DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(); //注入数据源 transactionManager.setDataSource(dataSource); return transactionManager; } }service类
import com.atguigu.spring5.config.TxConfig; import com.atguigu.spring5.service.UserService; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestDemo { @Test public void TestAccount(){ ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); UserService userService = context.getBean("userService", UserService.class); userService.BankTransfer1("1","2",500); } @Test public void TestAccount2(){ ApplicationContext context = new AnnotationConfigApplicationContext(TxConfig.class); UserService userService = context.getBean("userService", UserService.class); userService.BankTransfer1("1","2",500); } }dao接口
package com.atguigu.spring5.dao; public interface UserDao { void reduceMoney(String id1, int money); void addMoney(String id2, int money); }dao实现类
package com.atguigu.spring5.dao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; @Repository public class UserDaoImpl implements UserDao { @Autowired private JdbcTemplate jdbcTemplate; @Override public void reduceMoney(String id1, int money) { String sql = "update account set money = money - ? where id = ?"; jdbcTemplate.update(sql,money,id1); } @Override public void addMoney(String id2, int money) { String sql = "update account set money = money + ? where id = ?"; jdbcTemplate.update(sql,money,id2); } }测试类
import com.atguigu.spring5.config.TxConfig; import com.atguigu.spring5.service.UserService; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class TestDemo { @Test public void TestAccount2(){ ApplicationContext context = new AnnotationConfigApplicationContext(TxConfig.class); UserService userService = context.getBean("userService", UserService.class); userService.BankTransfer1("1","2",500); } }运行结果:
-
-
整个Spring5框架基于Java8,运行时兼容JDK9,许多不建议使用的类和方法在代码库中删除
-
Spring5框架核心容器支持@Nullable注解
- 可以使用在方法上面,属性上面,参数上面,表示可以为空
-
支持函数式风格GenericApplicationContext
-
Spring5支持整合JUnit5
-
SpringWebFlux
tereotype.Repository;
@Repository
public class UserDaoImpl implements UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public void reduceMoney(String id1, int money) {
String sql = "update account set money = money - ? where id = ?";
jdbcTemplate.update(sql,money,id1);
}
@Override
public void addMoney(String id2, int money) {
String sql = "update account set money = money + ? where id = ?";
jdbcTemplate.update(sql,money,id2);
}
}
```
测试类
```java
import com.atguigu.spring5.config.TxConfig;
import com.atguigu.spring5.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class TestDemo {
@Test
public void TestAccount2(){
ApplicationContext context =
new AnnotationConfigApplicationContext(TxConfig.class);
UserService userService = context.getBean("userService", UserService.class);
userService.BankTransfer1("1","2",500);
}
}
```
运行结果:
[外链图片转存中...(img-SxdR1Tsj-1651586731623)]
六、Spring5 新特性
-
整个Spring5框架基于Java8,运行时兼容JDK9,许多不建议使用的类和方法在代码库中删除
-
Spring5框架核心容器支持@Nullable注解
- 可以使用在方法上面,属性上面,参数上面,表示可以为空
-
支持函数式风格GenericApplicationContext
-
Spring5支持整合JUnit5
-
SpringWebFlux



