Spring5学习笔记

Spring概念

1)Spring是轻量级的开源的JavaEE框架

2)Spring可以解决企业应用开发的复杂性

3)Spring有两个核心部分:IOC和AOP

①IOC:控制反转,把创建对象过程交给Spring进行管理

②AOP:面向切面,不修改源代码进行功能增强

4)Spring特点

①方便解耦,简化开发

②AOP编程支持

③方便程序测试

④方便和其他框架进行整合

⑤方便进行事务操作

⑥降低API开发难度

IOC
1.IOC底层原理

1)xml解析、工厂模式、反射

2)IOC过程

第一步 xml配置文件,配置创建的对象

< bean id=“dao” class=“com.zty.UserDao” >< /bean > 进一步降低耦合

第二步 有service类和dao类,创建工厂类

class UserFactory{

​ public static UserDao getDao(){

​ String classValue = class属性值; // 1 xml解析

​ Class clazz = Class.forName(classValue); 2 通过反射创建对象

​ return (UserDao)clazz.newInstance();

​ }

}

3)IOC思想基于IOC容器完成,IOC容器底层就是对象工厂

Spring提供IOC容器实现两种方式:(两个接口)

①BeanFactory:IOC容器基本实现,是Spring内部的使用接口,不提供开发人员进行使用,加载配置文件时不会创建文件,在使用对象时才取创建对象

②ApplicationContext:BeanFactory接口的子接口,提供更多更强大的功能,一般面向开发人员进行使用,在加载配置文件的时候就会把配置文件对象进行创建

4)ApplicationContext接口有实现类

  • FileSystemXmlApplicationContext
  • ClassPathXmlApplicationContext
2.IOC接口(BeanFactory)
3.IOC操作Bean管理(基于xml配置文件方式实现)

1)什么是Bean管理

①Spring创建对象

②Spring注入属性

2)创建对象

< bean id=“user” class=“com.zty.spring5.User” > < /bean >

①在Spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建

②在bean标签中有很多属性,介绍常用的属性

id属性:唯一标识

class属性:类全路径(包类路径)

③创建对象时,默认也是执行无参数构造方法完成对象创建

3)注入属性

DI:依赖注入,就是注入属性

第一种注入方式:set方法注入

public void setName(String bname){

​ this.name = bname;

}

< bean id=“user” class=“com.zty.spring5.User” >

​ < property name=“bname” value=“易筋经” >< /property >

​ < property name=“bauthor” value=“达摩老祖” >< /property >

< /bean >

第二种注入方式:有参数构造注入

public Orders(String oname,String address){

​ this.oname = oname;

​ this.address = address;

}

< bean id=“orders” class=“com.zty.spring5.Orders” >

​ < constructor-arg name=“oname” value=“电脑” >< /constructor-arg >

​ < constructor-arg name=“address” value=“China” >< /constructor-arg >

< /bean >

4)注入其他类型属性

①字面量

  • null值

< property name=“address” >

​ < null/ >

< /property >

  • 属性值包含特殊符号

< property name=“address” >

​ < value > < ![CDATA[<<南京>>]] > < /value >

< /property >

②注入属性-外部bean

  • 创建两个类service类和dao类
  • 在service调用dao里面的方法
  • 在spring配置文件中进行配置

< bean id=“userService” class=“com.zty.spring5.service.UserService” >

​ < !-- 注入userDao对象

​ name属性:类里面属性名称

​ ref属性:创建userDao对象bean标签id值

​ -->

​ < property name=“userDao” ref=“userDaoImpl” > < /property >

< /bean >

< bean id=“userDaoImpl” class=“com.zty.spring5.dao.UserDaoImpl” > < /bean >

③注入属性-内部bean

  • 一对多关系:部门和员工

  • 在实体类之间表示一对多关系,员工表示所属部门,使用对象类型属性进行表示

  • 在spring文件中进行配置

< bean id=“emp” class=“com.zty.spring5.bean.Emp” >

​ < !-- 设置两个普通属性 – >

​ < property name=“ename” value=“lucy” > < /property >

​ < property name=“gender” value=“女” > < /property >

​ < !-- 设置对象类型属性 – >

​ < property name=“dept” >

​ < bean id=“dept” class=“com.zty.spring5.bean.Dept” >

​ < property name=“dname” value=“安保部” > < /property >

​ < /bean >

​ < /property >

< /bean >

④注入属性-级联赋值

  • 第一种写法

< bean id=“emp” class=“com.zty.spring5.bean.Emp” >

​ < !-- 设置两个普通属性 – >

​ < property name=“ename” value=“lucy” > < /property >

​ < property name=“gender” value=“女” > < /property >

​ < !-- 级联赋值 – >

​ < property name=“dept” ref=“dept” > < /property >

< /bean >

< bean id=“dept” class=“com.zty.spring5.bean.Dept” >

​ < property name=“dname” value=“财务部” > < /property >

< /bean >

  • 第二种写法

需要生成dept的get方法

< bean id=“emp” class=“com.zty.spring5.bean.Emp” >

​ < !-- 设置两个普通属性 – >

​ < property name=“ename” value=“lucy” > < /property >

​ < property name=“gender” value=“女” > < /property >

​ < !-- 级联赋值 – >

​ < property name=“dept” ref=“dept” > < /property >

​ < property name=“dept.dname” value=“技术部” > < /property >

< /bean >

< bean id=“dept” class=“com.zty.spring5.bean.Dept” >

​ < property name=“dname” value=“财务部” > < /property >

< /bean >

5)注入集合属性

①注入数组类型属性

< bean id=“stu” class=“com.zty.spring5.collectiontype.Stu” >

​ < property name=“courses” >

​ < array >

​ < value >java课程< /value >

​ < value >数据库课程< /value >

​ < /array >

​ < /property >

< /bean >

②注入List集合类型属性

< bean id=“stu” class=“com.zty.spring5.collectiontype.Stu” >

​ < property name=“list” >

​ < list >

​ < value >张三< /value >

​ < value >小三< /value >

​ < /list >

​ < /property >

< /bean >

③注入Map集合类型属性

< bean id=“stu” class=“com.zty.spring5.collectiontype.Stu” >

​ < property name=“maps” >

​ < map >

​ < entry key=“JAVA” value=“java” >< /entry >

​ < entry key=“PHP” value=“php” >< /entry >

​ < /map >

​ < /property >

< /bean >

④在集合里面设置对象类型值

< bean id=“stu” class=“com.zty.spring5.collectiontype.Stu” >

​ < property name=“courseList” >

​ < list >

​ < ref bean=“course1” >< /ref >

​ < ref bean=“course2” >< /ref >

​ < /list >

​ < /property >

< /bean >

< !–创建多个对象-- >

< bean id=“course1” class=“com.zty.spring5.collectiontype.Course” >

​ < property name=“cname” value=“Spring5框架” >< /property >

< /bean >

< bean id=“course2” class=“com.zty.spring5.collectiontype.Course” >

​ < property name=“cname” value=“MyBatis框架” >< /property >

< /bean >

⑤把集合注入部分提取出来

在spring配置文件中引入名称空间util

xmlns:util=“http://www.springframework.org/schema/util”

xsi:schemaLocation=“http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd”

< util:list id=“bookList” >

​ < value >易筋经< /value >

​ < value >九阴真经< /value >

​ < value >九阳神功< /value >

< /util:list >

< bean id=“book” class=“com.zty.spring5.collectiontype.Book” >

​ < property name=“list” ref=“bookList” >< /property >

< /bean >

6)IOC操作Bean管理(FactoryBean)

Spring有两种类型bean,一种普通bean,另外一种工厂bean(FactoryBean)

  • 普通bean:在配置文件中定义的bean类型就是返回类型

  • 工厂bean:在配置文件中定义的bean类型可以和返回类型不一样

第一步 创建类,让这个类作为工厂bean,实现接口FactoryBean

第二部 实现接口里面的方法,在实现的方法中定义返回的bean类型撒旦大神

7)IOC操作Bean管理(bean作用域)

①在Spring里面,设置创建bean实例是单实例还是多实例

②在Spring里面,默认情况下,创建的bean是单实例对象

③如何设置单实例还是多实例

  • 在spring配置文件bean标签里面有属性(scope)用于设置单实例还是多实例
  • scope属性值
  • 第一个值 默认值 singleton 表示是单实例对象
  • 第二个值 prototype 表示是多实例对象
  • singleton和prototype的区别
  • 设置scope值是singleton时,加载spring配置文件时就会创建单实例对象
  • 设置scope值是prototype时,在调用getBean方法时创建多实例对象

8)IOC操作Bean管理(bean生命周期)

①通过构造器创建bean实例(无参构造)

②为bean的属性设置值和对其他bean引用(调用set方法)

③把bean的实例传递给bean后置处理器的方法postProcessBeforeInitialization

④调用bean的初始化的方法(需要进行配置)

⑤把bean的实例传递给bean后置处理器的方法postProcessAfterInitialization

⑥bean可以使用了(对象获取到了)

⑦当容器关闭的时候,调用bean销毁的方法(需要进行配置销毁的方法)

9)IOC操作Bean管理(xml自动装配)

自动装配:根据指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行装入

< !–实现自动装配

​ bean标签属性autowire,配置自动装配

​ autowire属性常用有两个值:

​ byName根据属性名称注入,注入值bean的id值和类属性名称一样

​ byType根据属性类型注入

–>

10)IOC操作Bean管理(外部属性文件)

直接配置数据库信息

①配置德鲁伊连接池

②引入德鲁伊连接池依赖jar包

< bean id=“dataSource” class=“com.alibaba.druid.pool.DruidDataSource” >
< property name=“driverClassName” value=“com.mysql.jdbc.Driver” >< /property >
< property name=“url” value=“jdbc:mysql://localhost:3306/userDb” >< /property >
< property name=“username” value=“root” >< /property >
< property name=“password” value=“123456” >< /property >
< /bean >

引入外部属性文件配置数据库连接池

①创建外部属性文件,properties格式文件,写数据库信息

②把外部properties属性文件引入到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配置文件中使用标签引入外部属性文件

<context:property-placeholder location=“classpath:jdbc.properties” />

< bean id=“dataSource” class=“com.alibaba.druid.pool.DruidDataSource” >
< property name=“driverClassName” value=“ j d b c . d r i v e r " > < / p r o p e r t y > < p r o p e r t y n a m e = " u r l " v a l u e = " {jdbc.driver}" >< /property > < property name="url" value=" jdbc.driver"></property><propertyname="url"value="{jdbc.url}” >< /property >
< property name=“username” value=“ j d b c . u s e r n a m e " > < / p r o p e r t y > < p r o p e r t y n a m e = " p a s s w o r d " v a l u e = " {jdbc.username}" >< /property > < property name="password" value=" jdbc.username"></property><propertyname="password"value="{jdbc.password}” >< /property >
< /bean >

4.IOC操作Bean管理(基于注解方式实现)

1)什么是注解

①注解是代码特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值…)

②注解作用在类上面,方法上面,属性上面

③使用注解的目的:简化xml配置

2)Spring针对Bean管理中的创建对象提供注解

① @Component

② @Service

③ @Controller

④ @Respository

*上面四个注解的功能是一样的,都可以用来创建bean实例

3)基于注解方式实现对象创建

①引入依赖spring-aop.jar

②开启组件扫描(之前要引入名称空间context)

< context:component-scan base-package=“com.zty.spring5.service,com.zty.spring5.dao” >< /context:component-scan >

若要扫描多个包,多个包使用逗号隔开也可以扫描包的上层目录

③创建类,在类上面添加创建对象的注解

@Component(value=“userService”) //< bean id=“userService” class=“…” >

value属性值可以省略不写,默认值是类名称,首字母小写

④开启组件扫描细节配置

示例1

< context:component-scan base-package=“com.zty.spring5” use-default-filters=“false” >

​ < context:include-filter type=“annotation”

​ expression=“org.springframework.stereotype.Controller”/ >

< /context:component-scan >

use-default-filters="false"表示现在不使用默认filter,自己配置filter

context:include-filter设置扫描哪些内容

示例2

< context:component-scan base-package=“com.zty.spring5” >

​ < context:exclude-filter type=“annotation”

​ expression=“org.springframework.stereotype.Controller”/ >

< /context:component-scan >

context:exclude-filter设置哪些内容不进行扫描

4)基于注解方式实现属性注入

@AutoWired:根据属性类型进行自动装配

​ ①把service和dao对象创建,在service和dao类添加创建对象注解

​ ②在service中注入dao对象,在service类添加dao类型属性,不需要添加set方法,在属性上面使用注解

@Qualifier:根据属性名称进行注入

​ 要和@AutoWired一起使用

​ @Qualifier(value=“userDaoImpl”) 区分哪个对象

@Resource:可以根据类型注入,也可以根据名称注入

​ 根据类型注入:@Resource

​ 根据名称注入:@Resource(name=“userDaoImpl”)

@Value:注入普通类型属性

​ @Value(value=“abc”)

5)完全注解开发

①创建配置类,替代xml配置文件

@Configuration

@ComponentScan(basePackages={“com.zty”})

public class SpringConfig{}

②编写测试类

/* ApplicationContext context = new ClassPathXmlApplicationContext(“bean1.xml”); */

ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);

UserService userService = context.getBean(“userService”,UserService.class);

System.out.println(userService);

userService.add();

AOP
1.概念

1)什么是AOP

​ ①面向切面编程,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了程序的开发效率。

​ ②通俗描述:不通过修改源代码方式,只在主干功能里面添加新功能

​ ③具体举例

在这里插入图片描述

2.AOP底层原理

1)AOP底层使用动态代理

有两种情况动态代理

第一种 有接口情况,使用JDK动态代理

创建接口实现类的代理对象,增强类的方法

在这里插入图片描述

第二种 没有接口情况,使用CGLIB动态代理

创建子类的代理对象,增强类的方法

在这里插入图片描述

3.AOP-操作术语

1)连接点

类里面哪些方法可以被增强,这些方法就叫连接点

2)切入点

实际被真正增强的方法,称为切入点

3)通知(增强)

实际增强的逻辑部分称为通知(增强)

通知有多种类型,包括前置通知、后置通知、环绕通知、异常通知、最终通知(finally)

4)切面(是动作)

把通知应用到切入点的过程

4.AOP操作

1)Spring框架一般都是基于AspectJ实现AOP操作

AspectJ不是Spring组成部分,独立AOP框架,一般把AspectJ和Spring框架一起使用,进行AOP操作

2)基于AspectJ实现AOP操作

基于xml配置文件实现

①创建两个类,增强类和被增强类,创建方法

②在spring配置文件中创建两个类对象

< bean id=“book” class=“com.zty.spring5.aopxml.Book” >< /bean >

< bean id=“bookProxy” class=“com.zty.spring5.aopxml.BookProxy” >< /bean >

③在spring配置文件中配置切入点

< aop:config >

​ < aop:pointcut id=“p” expression=“execution(* com.zty.spring5.aopxml.Book.buy(…))”/ >

​ < aop:aspect ref=“bookProxy”>

​ < aop:before method=“before” pointcut-ref=“p”/ >

​ < /aop:aspect >

< /aop:config >

基于注解方式实现(一般实际用这种方式)

①创建类,在类里面定义方法

public class User {

​ public void add(){

​ System.out.println(“add…”);

​ }

}

②创建增强类(编写增强逻辑)

在增强类里面创建方法,让不同方法代表不同的通知类型

public class UserProxy {

​ public void before(){

​ System.out.println(“before…”);

​ }

}

③进行通知的配置

引入名称空间context和aop

在spring配置文件中,开启注解扫描

< context:component-scan base-package=“com.zty.spring5.aopanno” >< /context:component-scan >

使用注解创建User和UserProxy对象

@Component

在增强类上面添加注解@Aspect

在spring配置文件中开启生成代理对象

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

④配置不同类型的通知

在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置

前置通知@Before(value=“execution(* com.zty.spring5.aopanno.User.add(…))”)

后置通知(返回通知)@AfterReturning(value=“execution(* com.zty.spring5.aopanno.User.add(…))”)

最终通知@After(value=“execution(* com.zty.spring5.aopanno.User.add(…))”)

异常通知@AfterThrowing(value=“execution(* com.zty.spring5.aopanno.User.add(…))”)

环绕通知@Around(value=“execution(* com.zty.spring5.aopanno.User.add(…))”)

⑤相同的切入点抽取

@Pointcut(value=“execution(* com.zty.spring5.aopanno.User.add(…))”)

public void pointdemo(){}

@Before(value=“pointdemo”)

⑥有多个增强类对同一个方法进行增强,设置增强优先级

在增强类上面添加注解@Order(数字类型值),数字类型值越小优先值越高

3)在项目工程里面引入AOP相关依赖

4)切入点表达式

①作用:知道对哪个类里面的哪个方法进行增强

②语法结构:

execution( [权限修饰符] [返回类型] [类全路径] [方法名称] ([参数列表]) )

JdbcTemplate
1.概念和准备

1)概念

Spring框架对JDBC进行封装,使用JdbcTemplate方便实现对数据库的操作

2)准备工作

①引入相关jar包

②在spring配置文件中配置数据库连接池

< bean id=“dataSource” class=“com.alibaba.druid.pool.DruidDataSource” >
< property name=“driverClassName” value=“com.mysql.jdbc.Driver” >< /property >
< property name=“url” value=“jdbc:mysql://localhost:3306/userDb” >< /property >
< property name=“username” value=“root” >< /property >
< property name=“password” value=“123456” >< /property >
< /bean >

③配置JdbcTemplate对象,注入DataSource

< bean id=“jdbcTemplate” class=“org.springframework.jdbc.core.JdbcTemplate” >

​ < property name=“dataSource” ref=“dataSource” >< /property >

< /bean >

④创建service类,创建dao类,在dao中注入jdbcTemplate对象

2.JdbcTemplate操作数据库

1)添加、修改和删除

①对应数据库表创建实体类

②在dao中进行数据库添加操作

调用JdbcTemplate对象里面update方法实现添加操作

update(String sql,Object… args)

第一个参数:sql语句

第二个参数:可变参数,设置sql语句值

@Override

public void delete(String id){

​ String sql = “delete from t_book where user_id=?”;

​ int update = jdbcTemplate update(sql,id);

​ System.out.println(update);

}

2)查询

返回某个值

@Override

public int selectCount( ){

​ String sql = "select count(*)from t_book ";

​ Integer count = jdbcTemplate.queryForObject(sql,Integer.class);

​ return conunt;

}

返回某个对象

第一个参数:sql语句

第二个参数:RowMapper,是接口,针对返回不同类型的数据,使用这个接口里面的实现类完成数据封装

第三个参数:sql语句值

@Override

public Book findBookInfo(String id){

​ String sql = “select * from t_book where user_id=?”;

​ jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper< Book >(Book.class),id);

​ return Book;

}

返回某个集合

场景:查询图书列表分页

@Override

public List< Book > findAllBook(){

​ String sql = “select * from t_book”;

​ List< Book > bookList = jdbcTemplate.query(sql,new BeanPropertyRowMapper< Book >(Book.class));

​ return bookList;

}

3)批量操作(操作表里面的多条记录)

batchUpdate(String sql,List< Object[] >batchArgs)

第一个参数:sql语句

第二个参数:List集合,添加多条记录的数据

批量添加操作

@Override

public void batchAddBook(List< Object[] >batchArgs){

​ String sql = “insert into t_book values(?,?,?)”;

​ int[] ints = jdbcTemplate.batchUpdate(sql,batchArgs);

​ System.out.println(Array.toString(ints));

}

批量修改操作

@Override

public void batchUpdateBook(List< Object[] >batchArgs){

​ String sql = “update t_book set username = ?,ustatus = ? where user_id = ?”;

​ int[] ints = jdbcTemplate.batchUpdate(sql,batchArgs);

​ System.out.println(Array.toString(ints));

}

批量删除操作

@Override

public void batchDeleteBook(List< Object[] >batchArgs){

​ String sql = “delete from t_book where user_id = ?”;

​ int[] ints = jdbcTemplate.batchUpdate(sql,batchArgs);

​ System.out.println(Array.toString(ints));

}

事务管理
1.事务的概念

1)事务是数据库操作最基本的单元,逻辑上的一组操作,要么都成功,要么都失败

典型场景:银行转账

2)事务的四大特性(ACID)

①原子性 ②一致性 ③持续性 ④隔离性

2.搭建事务操作环境

在这里插入图片描述

①创建数据库表,添加记录

②创建service,搭建dao,完成对象注入和注入关系,service注入dao,在dao中注入JdbcTemplate,在JdbcTemplate中注入DataSource

③在dao中创建两个方法:多钱和少钱的方法,在service中创建转账的方法

@Override

public void reduceMoney( ){

​ String sql = “update t_account set money = money - ? where username = ?”;

​ jdbcTemplate.update(sql,100,“lucy”);

}

@Override

public void addMoney( ){

​ String sql = “update t_account set money = money + ? where username = ?”;

​ jdbcTemplate.update(sql,100,“mary”);

}

public void accountMoney( ){

​ userDao.reduceMoney();

​ userDao.addMoney();

}

3.Spring事务管理介绍

1)事务添加到JavaEE三层结构中的service层(业务逻辑层)

2)在Spring中进行事务管理操作

有两种方式:编程式事务管理和声明式事务管理

3)声明式事务管理

事务参数

  • propagation:事务传播行为

当一个事务被另外一个事务方法调用的时候,这个事务方法如何进行

REQUIRED:如果有事务在运行,当前的方法就在这个事务内运行,否则,就启动一个新的事务,并在自己的事务内运行

REQUIRED_NEW:当前的方法必须启动新事务,并在它自己的事务内运行,如果有事务正在运行,应该将它挂起

SUPPORTS:如果有事务在运行,当前的方法就在这个事务内运行,否则它可以不运行在事务中

  • ioslation:事务隔离级别

事务中有一种特性称为隔离性,多事务操作之间不会产生影响,不考虑隔离性会产生很多问题

三个读问题:脏读、不可重复读、幻读

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

不可重复读:一个未提交事务读取到另一提交事务的修改数据

幻读:一个未提交事务读取到另一提交事务的添加数据

通过设置事务的隔离级别来解决读问题

脏读不可重复读幻读
READ UNCOMMITTED(读未提交)
READ COMMITTED(读已提交)
REPEATABLE READ(可重复读)
SERIALIZABLE(串行化)
  • timeout:超时时间

事务需要在一定的时间内进行提交,如果不提交需要进行回滚

默认值是-1,设置时间以秒为单位进行计算

  • readOnly:是否只读

readOnly默认值false,表示可以查询,可以添加修改删除操作

设置为true后只能进行查询操作

  • rollbackFor:回滚

设置出现哪些异常进行事务回滚

  • noRollbackFor:不回滚

设置出现哪些异常不进行事务回滚

基于注解方式

①在spring配置文件中配置事务管理器

< !-- 创建事务管理器 -->

< bean id=“transactionManager” class=“org.springframework.jdbc.datasource.DataSourceTransactionManager” >

​ < !-- 注入数据源 -->

​ < property name=“dataSource” ref=“dataSource” >< /property >
< /bean >

②在spring配置文件中引入名称空间tx

< !-- 开启事务注解 -->

< tx:annotation-driven transaction-manager=“transactionManager” >< /tx:annotation-driven >

③在service类上面(获取service类里面的方法上面)添加事务注解

@Transactional

添加到类上表明这个类里面所有的方法都添加了事务

添加到方法上则只为这个方法添加事务

基于xml配置文件方式

在spring配置文件中进行配置

①配置事务管理器

< !-- 创建事务管理器 -->

< bean id=“transactionManager” class=“org.springframework.jdbc.datasource.DataSourceTransactionManager” >

​ < !-- 注入数据源 -->

​ < property name=“dataSource” ref=“dataSource” >< /property >
< /bean >

②配置通知

< tx:advice id=“txadvice” >

​ < !-- 配置事务参数 -->

​ < tx:attributes >

​ < !-- 指定哪种规则的方法上面添加事务 -->

​ < tx:method name=“accountMoney” propagation=“REQUIRED”/ >

​ < tx:method name=“account*”/ >

​ < /tx:attributes >

< /tx:advice >

③配置切入点和切面

< aop:config >

​ < !-- 配置切入点 -->

​ < aop:pointcut id=“pt” expression=“execution(* com.zty.spring5.service.UserService.*(…))” >

​ < !-- 配置切面 -->

​ < aop:advisor advice-ref=“txadvice” pointcut-ref=“pt”/ >

< /aop:config >

完全注解方式

创建配置类,使用配置类替代xml配置文件

@Configuration //配置类

@ComponentScan(basePackages = “com.zty”) //组件扫描

@EnableTransactionManagement //开启事务

public class TxConfig{

​ //创建数据库连接池

​ @Bean

​ public DruidDataSource getDruidDataSource(){

​ DruidDataSource dataSource = new DruidDataSource();

​ dataSource.setDriverClassName(“”);

​ dataSource.setUrl(“”);

​ dataSource.setUsername(“”);

​ dataSource.setPassword(“”);

​ return dataSource;

​ }

​ //创建JdbcTemplate对象

​ @Bean

​ public JdbcTemplate getJdbcTemplate(DataSource dataSource){

​ //到IOC容器中根据类型找到dataSource

​ JdbcTemplate jdbcTemplate = new JdbcTemplate();

​ jdbcTemplate.setDataSource(dataSource);

​ return jdbcTemplate;

​ }

​ //创建事务管理器对象

​ @Bean

​ public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource){

​ DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();

​ transactionManager.setDataSource(dataSource);

​ return transactionManager;

​ }

}

4)在Spring中进行声明式事务管理,底层使用AOP原理

5)Spring事务管理API

提供一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类

Spring5新特性

1)整个Spring5框架的代码基于Java8实现,运行时兼容JDK9,许多不建议使用的类和方法在代码库中删除

2)Spring5框架自带了通用的日志框架

Spring5已经移除Log4JConfigListenter,官方建议使用Log4j2

Spring5框架整合Log4j2

①引入jar包

②创建Log4j2.xml配置文件(名字固定)

3)Spring5框架核心容器支持@Nullable注解

@Nullable注解可以使用在方法上面,属性上面,参数上面,表示方法返回可以为空,属性值可以为空,参数值可以为空

4)Spring5核心容器支持函数式风格GenericApplicationContext

函数式风格创建对象,交给spring进行管理

5)Spring5支持整合JUnit5

整合JUnit4

①引入Spring相关针对测试的依赖

②创建测试类,使用注解方式完成

@RunWith(SpringJUnit4ClassRunner.class) //单元测试框架

@ContextConfiguration(“classpath:bean1.xml”) //加载配置文件

public class JTest4{

​ @Autowired

​ private UserService userService;

​ @Test

​ public void test1(){

​ userService.accountMoney();

​ }

}

整合JUnit5

①引入JUint5的jar包

②创建测试类,使用注解方式完成

@ExtendWith(SpringExtension.class)

@ContextConfiguration(“classpath:bean1.xml”)

//也可使用@SpringJUintConfig(locations=“classpath:bean1.xml”)代替上边两个注解

public class JTest5{

​ @Autowired

​ private UserService userService;

​ @Test

​ public void test1(){

​ userService.accountMoney();

​ }

}

6)SpringWebFlux

①SpringWebFlux介绍

是Spring5添加的新的模块,用于web开发的,功能SpringMVC类似的,WebFlux是使用当前一种比较流行的响应式编程而出现的框架

使用传统Web框架,比如SpringMVC,这些是基于Servlet容器,WebFlux是一种异步非阻塞的框架,异步非阻塞的框架在Servlet3.1以后才支持,核心是基于Reator的相关API实现的

异步和同步针对调用者,调用者发出请求,如果等着对方回应之后才去做其他事情就是同步,如果发送请求之后不等着对方回应就去做其他事情就是异步

阻塞和非阻塞针对被调用者,被调用者收到请求之后,做完请求之后才给出反馈就是阻塞,收到请求之后马上给出反馈再去做事情就是非阻塞

WebFlux特点

第一:非阻塞式:在有限资源下,提高系统吞吐量和伸缩性,以Reactor为基础实现响应式编程

第二:函数式编程:Spring5框架基于java8,WebFlux使用Java8函数式编程方式实现路由请求

比较SpringMVC和SpringWebFlux

第一:两个框架都可以使用注解方式,都运行在Tomcat等容器中

第二:SpringMVC采用命令式编程,WebFlux采用异步响应式编程

②响应式编程

响应式编程是一种面向数据流和变化传播的编程范式,这意味着可以在编程语言中很方便地表达静态或动态的数据流,而计算机相关模型会自动将变化的值通过数据流进行传播

响应式编程操作中,Reactor是满足Reactive规范的框架

Reactor有两个核心类,Mono和Flux,这两个类都实现了接口Publisher,它提供了丰富的操作符。Flux对象实现发布者,返回N个元素;Mono实现发布者,返回0或者1个元素

Flux和Mono都是数据流的发布者,使用Flux和Mono都可以发出三种数据信号:元素值、错误信号、完成信号。其中错误信号和完成信号都代表终止信号,终止信号用于告诉订阅者数据流结束了,错误信号终止数据流同时把错误信息传递给订阅者

三种信号的特点

错误信号和完成信号都是终止信号,不能共存的

如果没有发送任何元素值,而是直接发送错误信号或者完成信号,表示是空数据流

如果没有错误信号,没有完成信号,表示是无限数据流

操作符:对数据流进行一道道操作,称为操作符,比如工厂流水线

第一:map元素映射为新元素

第二:flatMap元素映射为流。把每个元素转换成流,把转换之后的多个流合并成大的流

③WebFlux执行流程和核心API

SpringWebFlux基于Reactor,默认使用容器是Netty,Netty是高性能的NIO框架,异步非阻塞的框架

SpringWebFlux执行过程和SpringMVC是相似的

SpringWebFlux核心控制器DispatchHandle:,实现接口WebHandler,负责请求的处理

HandlerMapping:请求查询到处理的方法

HandlerAdapter:真正负责请求处理

HandlerResultHandler:响应结果处理

SpringMVC方式实现,同步阻塞的方式,基于SpringMVC+Servlet+Tomcat

SpringWebFlux方式实现,异步非阻塞方式,基于SpringWebFlux+Reactor+Netty

④SpringWebFlux(基于注解编程模型)

⑤SpringWebFlux(基于函数式编程模型)

在使用函数式编程模型操作的时候,需要自己初始化服务器

SpringWebFlux实现函数式编程,两个核心接口:RouterFunction(实现路由功能,请求转发给对应的handler)和HandlerFunction(处理请求生成响应的函数)

核心任务就是定义两个函数式接口的实现并且启动需要的服务器

SpringWebFlux请求和响应不再是ServletRequest和ServletResponse,而是ServerRequest和ServerResponse

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zzzty_cs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值