1. Spring5基本介绍
-
介绍: Spring是一个轻量级的开源的J2EE框架。
-
目的: 解决企业应用开发的复杂性。
-
Spring的核心部分
Spring有两个重要的核心部分(不止): IOC AOP。
IOC: 控制反转, 把创建对象的过程交给Spring管理。
Aop: 面向切面, 不修改源代码的情况下进行功能的增强。 -
Spring框架的特点
(1) 方便解耦合, 简化开发。
(2) Aop编程支持。
(3) 支持声明式事务, 降低事务操作的难度。
(4) 方便程序测试。
(5) 方便和其他框架整合(mybatis、SpringMVC…)。
(6) 降低JavaEE API调用难度。
(7) Spring源码是Java学习经典范例。 -
下载Spring相关依赖
百度搜索Spring官方
选中projects --> SpringFrameWork
下载GA(稳定)版本的Spring
点击猫头
往下翻, 找到并点击这个
往下翻, 找到并点击这个
选中Artifacts
找到release/org/springframework/spring/ 复制地址登入下载即可
搜索地址: https://repo.spring.io/release/org/springframework/spring/
- Spring模块图
2. IOC
2.1 阶段所需jar包
2.2 IOC简述
IOC: 控制反转
即控制权的转移,将我们创建对象的方式反转了,以前对象的创建是由我们开发人员自己维护,包括依赖关系也是自己注入。使用了spring之后,对象的创建以及依赖关系可以由spring完成创建以及注入,反转控制就是反转了对象的创建方式,从我们自己创建反转给了程序创建(spring)
作用: 降低程序耦合度
实现IOC思想需要DI做支持
DI是IOC中一种具体的实现, 表示依赖注入, 依赖注入需要在创建对象的基础上完成。
DI: Dependency Injection 依赖注入
spring这个容器中,替你管理着一系列的类,前提是你需要将这些类交给spring容器进行管理,然后在你需要的时候,不是自己去定义,而是直接向spring容器索取,当spring容器知道你的需求之后,就会去它所管理的组件中进行查找,然后直接给你所需要的组件.
注入方式: 1.set方式注入 2.构造方法注入 3.字段注入
注入类型: 1.值类型注入 2.引用类型注入
2.3 IOC底层原理
实现技术: 反射、XML解析技术、工厂模式
原理图
2.4 IOC接口
- IOC思想基于IOC容器完成,IOC底层就是对象工厂
- Spring提供IOC容器实现两种方式(两个接口)
ApplicationContext & BeanFactory- BeanFactory接口(不提供给开发人员使用)
(1) spring的原始接口,针对原始接口的实现类功能较为单一
(2) beanFactory接口实现类的容器,特点是每次在获得对象时才会创建对象 - ApplicationContext接口(提供给开发人员使用)
(1) 每次容器启动时就会创建容器中配置的所有对象
(2) 提供了更多功能
(3) BeanFactory的子接口
- BeanFactory接口(不提供给开发人员使用)
- ApplicationContext的实现类
- 从硬盘的绝对路径下加载配置文件: FileSystemXmlApplicationContext
- 从src下加载配置文件:ClassPathXmlApplicationContext
2.5 什么是bean管理
- Spring创建对象
- Spring注入属性
bean管理操作有两个方式
- 基于XML配置文件方式实现
- 基于注解方式实现
2.5.1 bean的元素属性
-
bean元素:使用该元素描述需要spring容器管理对象
-
name属性:给被管理的对象起个名字,获得对象时getBean(“name值”)
-
class属性:被管理对象的完整类名,类全路径
-
id属性:与name属性一模一样,名称不可重复,不能使用特殊字符, 唯一标识
name和id之间的一些注意点
- 配置两个相同的 id 或者 name 都不能通过。
- 如果既配置了 id ,也配置了 name ,则两个都生效。如果id和name都没有指定,则用类全名作为name,如,则你可以通过getBean(“com.stamen.BeanLifeCycleImpl”)返回该实例。
- 如果配置基本类的时候,注解和配置文件都使用的时候,注解和配置文件中 name 相同的时候, 则两个冲突,配置文件生效。
- 如果配置基本类的时候,注解和配置文件都使用的时候,注解和配置文件中 name 不相同的时候, 则两个不冲突,都能够生效。
2.5.2 bean的作用域
在Spring中, 设置创建bean实例是单实例还是多实例
在Spring中, 默认情况下bean是单实例。
如何设置单实例还是多实例
在Spring配置文件bean标签中的scope属性设置是否是单实例还是多实例
scope属性值: 默认值 singleton、prototype、request(创建对象时放到request域中)、session(创建对象时放到session域中)、
singleton和prototype的区别
- singleton是单实例, prototype是多实例
- 设置scope值是singleton是单实例时, 加载配置文件时就会完成创建单实例对象
设置scope值是prototype是多实例时, 在调用getBean方法的时候才会创建多实例对象
2.5.3 bean的生命周期
- 通过构造器创建bean实例(无参数构造器)
- 为bean的属性设置值和对其他bean的一个引用
- 把bean实例传递bean后置处理器的方法并返回
- 调用bean的初始化的方法(需要配置)
- 把bean实例传递bean后置处理器的方法并返回
- bean可以使用了(对象获取完成)
- 当容器关闭的时候, 调用bean的销毁方法(需要配置)
后置处理器的创建
- 创建类、实现接口BeanPostProcessor, 创建后置处理器。
- 重写前置和后置方法。
2.5.4 bean管理XML方式
基于xml方式创建对象
在Spring配置文件中, 使用bean标签, bean标签添加对应属性, 就可以实现对象创建。
- 执行无参数构造方法完成对象的创建
- 通过有参数构造方法完成对象的创建并初始化
基于xml方式注入属性
-
set注入
步骤
- 创建类, 定义属性和对应的set方法
- 在spring配置文件中配置对象的创建和属性的注入
-
有参构造器注入
步骤
- 创建类、类的属性、有参数构造器
- 在Spring配置文件中进行配置
可以使用索引(使用较少)
-
p名称空间注入
使用p名称空间注入, 可以简化xml操作
步骤:- 在xml文件上部引入p名称空间
- 在bean标签中编写属性
-
注入空值和特殊符号
-
字面量
(1) null值
(2) 属性值中包括特殊符号
-
-
外部bean注入
(1) 创建两个类Service类和dao类
(2) 在Service调用dao里面的方法
Service层中有一个私有化的dao对象, 通过set/有参数构造器进行对象初始化
(3) 在Spring配置文件中进行配置
-
内部注入bean
-
级联赋值
这种写法需要提供get方法
-
注入数组类型数据演示(普通数据)
-
注入Collection类型数据演示(普通数据)
-
注入map类型数据演示(普通数据)
-
往集合、数组中注入对象属性
第二种写法: 把集合注入的部分提取出来, 可以让多个集合/数组使用
步骤
(1) 在Spring配置文件中引入名称空间util
(2) 写法
工厂bean
- bean分为普通bean和工厂bean。
- 在配置文件中定义的bean类型就是返回类型的bean是普通bean。
- 在配置文件中定义的bean类型可以和返回类型不同的bean叫做工厂bean
创建工厂bean的步骤
- 创建类, 让这个类实现工厂bean, 并实现接口FactoryBean。
- 实现接口方法, 并在实现的方法中定义返回的bean类型
自动装配
bean标签属性autoWire配置自动装配
常用值:
byName 注入值bean的id值和类属性名称一样
byType
根据指定的装配规则(属性名称或者属性类型), Spring自动将匹配的属性值进行注入。
外部属性文件properties
2.5.5 bean管理注解方式
基于注解创建对象
Spring中针对Bean管理中创建对象的注解
@Component(普通组件)
@Service(业务逻辑层、service)
@Controller(web层)
@Repository(dao层)
这四个注解功能一样,都可以创建bean实例
步骤
-
引入依赖
-
开启组件扫描
引入context名称空间
-
创建类, 添加注解
组件扫描配置
use-default-filters="false"的意思是不扫描那些注解
<context:component-scan base-package=“com.atguigu.springmvc” use-default-filters=“false”>
<context:include-filter type=“annotation”
expression=“org.springframework.stereotype.Controller”/>
</context:component-scan>
<context:component-scan base-package=“com.atguigu.springmvc”>
<context:exclude-filter type=“annotation”
expression=“org.springframework.stereotype.Controller”/>
</context:component-scan>
基于注解注入属性
注意: 记得引入名称空间和开启组件扫描
@Autowire: 根据属性类型进行自动装配
@Qualifier: 根据属性名称进行注入
AutoWired和Qualifier是组合使用的
AutoWired标识这个属性要被注入
而Qualifier是用来区分注入属性的类具体是哪个, value值和对应类创建对象的注解值value是相同的
@Resource: 可以根据类型注入, 可以根据名称注入
用法基本同Qualifier, 写法略有不同, @Resource(name=“注入类创建对象的注解value值”)
@Value: 注入普通类型属性
用法: @Value(值)
完全注解开发
创建配置类 使用注解@Configuration和@ComponentScan(basePackages={“包”})修饰
代替xml配置文件的作用。
配置类演示
这里的basePackages等同xml配置文件当中的class属性
通过new AnnotationConfigApplicationContext(配置类.class)读取配置类
3. AOP
3.1 AOP的基本概念
面向切面(方面)编程, 利用AOP可以对业务逻辑的各个部分进行隔离, 降低业务逻辑各部分之间的耦合度, 提高程序的可重用性, 提高开发效率。
通俗描述: Spring对动态代理的操作
3.2 AOP底层原理
AOP的底层使用动态代理实现
动态代理的常见情况
第一种 有接口, 使用JDK动态代理
创建接口实现类代理对象, 增强类的方法
第二种 没有接口, 使用CGLIB动态代理
创建子类的代理对象, 增强类的方法
3.3 AOP相关术语
连接点: 类里面可以被增强的方法
切入点: 实际被真正增强的方法
通知(增强): 实际被增强的逻辑部分
通知有多种类型:
- 前置通知: 执行方法前的增强部分
- 后置通知: 执行方法后的增强部分
- 环绕通知: 前后都会执行的部分
- 异常通知: 出现异常执行的部分
- 最终通知: 最后一定会执行的部分
切面: 把增强的逻辑应用到增强的方法中叫做切面,是一个过程。
3.4 使用AspectJ实现AOP操作
Spring框架一般都是基于AspectJ实现AOP操作
3.4.1 什么是AspectJ
AspectJ不是Spring组成部分, 独立AOP框架, 我们一般把AspectJ和Spring框架组合一起使用, 进行AOP操作。
3.4.2 引入AOP相关依赖
3.4.3 切入点表达式
作用: 知道对那个类里面的那个方法进行增强
语法结构
execution([权限修饰符][返回值类型][类全路径][方法名称]([ 参数列表 ] ))
示范1: 对com.atguigu.dao.BookDao类中的所有方法进行增强
execution(* com.atguigu.dao.BookDao.(…))
示范2: 对com.atguigu.dao.BookDao类中的add方法进行增强
execution( com.atguigu.dao.BookDao.add(…))
示范3:对com.atguigu.dao包下的所有类, 类中所有方法进行增强
execution(* com.atguigu.dao.*(…))
3.4.4 基于AspectJ实现AOP操作(注意引入名称空间)
3.4.4.1 基于xml配置文件实现
-
创建类和增强类
-
在spring配置文件中创建两个类的对象
-
在spring的配置文件中配置切入点
3.4.4.2 基于注解方式实现(注意开启扫描和引入空间)
-
创建类, 定义方法
-
创建增强类, 编写增强逻辑
在增强类中, 创建不同的方法, 对应不同的通知 -
进行通知的配置
在spring配置文件中, 开启注解的扫描(注意引入aop context名称空间)
使用注解创建类和增强类
-
在增强类上面添加注解@Aspect, 生成代理对象
-
在spring配置文件中开启生成代理对象
这一段可以在配置类中通过@EnableAspectJAutoProxy(proxyTargetClass=true)注解的方式代替
默认值是true 意思就是开启生成代理对象 -
配置不同类型的通知
@Before 前置通知
@After 后置通知
@AfterReturning 最终通知
@AfterThrowing 异常通知
@Around 环绕通知
在增强类的里面, 在作为通知方法上方添加通知类型注解, 使用切入点表达式配置内容
公共切入点提取
执行优先级
有多个增强类对同一个方法进行增强, 可以设置优先级来决定谁先执行谁后执行
在增强类的上面添加注解@Order(数字类型值) 数字值越小越高
4. JdbcTemplate操作数据库
4.1 什么是JdbcTemplate
-
Spring框架对JDBC进行封装, 使用JDBCTemplate可以很方便的实现对数据库进行增删改查操作
-
准备工作(记得引入名称空间和开启组件扫描)
(1) 引入相关jar包(注意引入数据库jar包和数据库连接池包)
(2) 在Spring配置文件中配置数据库连接池
也可以通过外部配置文件配置 (3) 配置JdbcTemplate对象, 注入dataSource
(4) 创建service类, 创建dao类, 往dao里注入jdbcTemplate对象
4.2 使用JdbcTemplate进行增删改操作
核心方法: jdbcTemplate.update(String sql,Object …orgs);
在dao的实现类中使用
删除和修改只需要修改SQL语句和形参即可
4.3 使用JdbcTemplate进行查询操作
查询并返回特殊值或对象, queryForObject(String sql,Class clazz)
第二个参数是返回值类型所在class
查询并返回集合
核心方法: query(String sql,BeanPropertyRowMapper<> b,Object …objs)
第二个参数是一个接口, 在构造器中写你需要的返回值类型
第三个参数是形参, 这里因为需求中不需要, 所以空着
4.4 JdbcTemplate批量操纵数据
批量的增加、删除、修改操作
方法: batchUpdate(String sql,List< Object[] > list)
第二个参数是你要插入/删除/修改的数据集合
5. Spring事务管理
5.1 声明式事务管理的概念
- 事务添加到service层(业务逻辑层)
- 在Spring中进行事务管理操作, 有两种方式: 编程式事务操作和声明式事务操作(使用)
- 可以通过注解或xml配置文件的方式实现
- 在Spring进行声明式事务管理. 底层使用AOP
5.2 Spring事务管理API
(1) 提供一个接口, 代表事务管理层, 这个接口针对不同的框架提供不同的实现类。
5.3 Spring注解声明式事务管理
-
在Spring的配置文件中配置事务管理器
-
在Spring的配置文件中开启事务注解
(1) 在Spring配置文件中引入名称空间tx
(2) 开启事务注解
-
在service类/方法上面添加事务注解@Transactional
(1) 如果把这个注解添加到类上面, 这个类里面所有的方法都添加事务。
(2) 如果把这个注解添加到方法上面, 为这个方法添加事务。
5.4 声明式事务管理参数配置
在service类上面添加注解@Transactional,在这个注解里面可以配置事务相关参数。
propagation: 事务传播行为
ioslation: 事务隔离级别
timeout: 超时时间
(1) 事务需要在一定时间内进行提交, 如果不提交就会回滚
(2) 默认值是-1, 设置时间以秒单位进行计算
readOnly: 是否只读
(1) 读:查询操作 写: 增删改操作
(2) readOnly默认值false, 表示可以查询, 可以添加删除修改操作
(3) readOnly是true, 设置为true之后, 只能查询
rollbackFor: 回滚
(1)设置出现那些异常进行事务回滚
noRollbackFor: 不回滚
(1)设置出现那些异常不进行事务回滚
5.5 通过xml配置声明式事务
- 配置事务管理器
- 配置通知
- 配置切入点和切面
5.6 完全注解声明式事务管理
创建配置类, 使用配置类替代xml配置文件。
6. Spring5新功能
6.1 整合日志框架
Spring5框架自带了通用的日志封装Log4j2
使用步骤:
-
引入相关的依赖
-
创建log4j2.xml并配置配置内容
-
执行程序时在控制台可以看见日志信息
6.2 Nullable注解和函数式注册对象
Spring5框架核心容器支持@Nullable注解
@Nullable注解可以使用在方法上面, 属性上面, 参数上面, 表示方法的返回值可以为空, 属性值可以为空, 参数值可以为空
使用在方法上
使用在参数中
使用在属性上
函数式风格创建对象
6.3 整合Junit5单元测试框架
- 整合Junit4
(1) 引入Spring相关针对测试的依赖
(2) 创建测试类,使用注解方式完成
- 整合Junit5
引入Junit5的依赖
可以使用这句来替代上面的@ExtendWith和@ContextConfiguration
6.4 WebFlux
6.4.1 WebFlux的基本介绍
SpringWebFiux是Spring5添加新的模块, 用于Web开发, 功能和SpringMVC类似, WebFlux是一种当前比较流行的响应式编程框架
使用传统的Web框架, 比如SpringMVC、这些都是基于Servlet容器上运行, WebFlux是一种异步非阻塞的框架,异步非阻塞的框架在Servlet3.1以后才支持, 核心是基于Reactor的相关API实现的。
6.4.2 术语解释
异步非阻塞
- 异步和同步: 针对调用者, 当我们的调用者发送请求, 如果等着对方回应之后才做其他的事情, 这种情况就是同步, 如果发送请求后不等对方回应就去做其他事情就是异步。
- 非阻塞和阻塞: 针对被调用者, 当被调用者收到请求, 执行完任务后才给出回馈就是阻塞, 收到请求之后马上给出回馈然后在作任务就是非阻塞。
6.4.3 WebFlux特点
- 非阻塞式: 在有限的资源下, 提高系统的吞吐量和伸缩性, 以Reactor为基础实现响应式编程。
- 函数式编程: Spring5框架基于JDK8, WebFlux使用JAVA8函数式编程方法实现路由请求。
- 与SpringMVC比较
(1) 两个框架都可以使用注解方式, 都运行在Tomcat等容器中
(2) SpringMVC采用命令式编程, WebFlux采用异步响应式编程
6.4.4 响应式编程
6.4.4.1 什么是响应式编程
响应式编程是一种面向数据流和变化传播的编程范式, 这意味着可以在编程语言中很方便地表达静态或动态的数据流, 而相关的计算模型会自动将变化的值通过数据流进行传播, 电子表格程序就是响应式编程的一个例子, 单元格可以包含字面值或类似"=B1+C1"的公式, 而包含公式的单元格的值会依据其他单元格的值的变化而变化
6.4.4.2 Reactor实现响应式编程
- 响应式编程操作中, Reactor是满足Reactive规范的框架。
- Reactor有两个核心类, Mono和Flux, 这两个类都实现了接口Publisher, 提供丰富操作符。Flux对象实现发布者, 返回N个元素, Mono实现反发布者, 返回0~1个元素。
- Flux和Mono都是数据流的发布者, 使用Flux和Mono都可以发出三种数据信号。元素值、错误信号、完成信号、错误信号和完成信号都代表终止信号, 终止信号用于告诉订阅者数据流结束了, 错误信号终止数据流同时把错误信息传递给订阅者。
6.4.4.3 SpringWebflux执行流程和核心API
SpringWebflux基于Reactor, 默认使用容器是Netty, Netty是高性能的NIO框架, 异步非阻塞的框架。