视频地址:https://www.bilibili.com/video/BV1Vf4y127N5?p=59
代码地址:https://gitee.com/empirefree/SpringBoot-summarize/tree/%E5%B0%9A%E7%A1%85%E8%B0%B7-Spring%E7%AF%87
Spring是轻量级JavaEE框架, 内部包含IOC和AOP
IOC: 控制反转,把对象创建,对象创建过程交给Spring管理
AOP:面向切面,不修改源代码进行功能增强
由于SpringBoot集成了Spring,所以不需要下载jar包,直接创建基本SpringBoot项目即可。
1. resource下写入bean.xml
1. 代码写入Spring配置文件
1. 利用配置获取user对象
inversion of control(控制反转):把对象创建和对象之间调用过程交给Spring管理
目的就是为了耦合性降低
内部原理:XML解析、工厂模式、反射
工厂模式:正常A 调用B是在A中new B,但是为保证高内聚,低耦合,在一个工厂类中new B,然后再A中调用工厂类。(类似于用户,部门,用户部门表关联一样)
1、定义XML配置文件
2、创建工厂类
class UserFactory{
public static UserDao getDao(){
String classValue = class属性值; //1、xml解析
Class clazz = Class.forName(classValue) //2、通过反射创建对象
return (UserDao)clazz.newInStance();
}
}
IOC容器底层就是对象工厂
实现方式
1、BeanFacotry:懒汉式加载对象(调用对象时创建对象,加载配置文件时不创建对象),但由于应在服务器启动时把资源、对象都创建好,所以不推荐使用
2、ApplicationContext:BeanFactory子接口,饿汉式加载对象(加载配置文件就创建对象),推荐使用
2.1 FileSystemXmlApplicationContext:需要加载盘路径
2.2 ClassPathXmlApplicationContext:只用写相对路径
Bean管理: 1、操作对象 2、注入属性
Bean管理操作方式 1、基于xml配置文件 2、基于注解
DI:依赖注入,即注入属性,就是IOC的一种具体实现
1、正常bean:xml中定义,然后context中获取
2、工厂bean:A类实现FactoryBean接口,自定义返回对象类型B类,可与与xml中定义类型不一样。
1、单例模式singleton:加载bean.xml文件获取(Spring默认)
2、多实例模式prototype:context.getBean的时候创建
(request, session)
后置处理器(七步)
1. 调用无参构造创建bean实例
2. 设置属性或其他bean引用,即set方法
3. bean实例传递给bean后置处理之前方法
4. 调用bean初始化方法
5. bean实例传递给bean后置处理之后方法
6. 获取对象
7. 销毁bean
自动装配:Spring根据属性名称或者属性类型进行bean注入
注解是代码特殊标记 格式:@注解名称(属性名称=属性值)
注解:作用在类、方法、属性上
目的:简化XML配置
@Component:创建任意一个对象
@Service:业务逻辑层创建对象
@Controller:web层创建对象
@Repository: dao层创建对象
注入属性步骤
0、都需要开启component扫描到对象
1、service, dao都先创建对象
2、service注入dao对象
@Autowired:根据属性类型注入,就是class值,不用再写set方法注入
@Qualified:配合@autowired使用,根据属性值注入,就是id,为了防止某个接口又多个实现,找不到实现类
@Resourse:javax中的类,默认类型注入,可以定义成名称id注入
@Value:普通类型注入
@Configuration: 类似于xml
AOP:不修改源代码的基础上,在主干功能上添加新功能
底层原理就是动态代理:分为jdk动态代理与cglib动态代理
动态代理:由于采用了反射,所以和静态代理区别是运行时确定对象类型,然后动态生成类字节码加载到jvm中。
jdk动态代理:创建接口的代理对象
cglib动态代理:创建子类的代理对象
参考:静态、动态代理 https://javaguide.cn/java/basis/proxy.html#_2-%E9%9D%99%E6%80%81%E4%BB%A3%E7%90%86
连接点:类中可以被增强的方法
切入点:实际被增强的方法
通知:实际增强的逻辑部分就叫通知(前置,后置,环绕,异常,最终finally通知)
切面:只是一个动作,表示把通知应用到切入点
举例:登录类中有多个方法(连接点),对登录方法(切入点)进行切入,写入的代码就叫通知,这整个动作就叫切面
采用AspectJ实现。Aspectj不是Spring组成,是独立的AOP框架,基于注解或xml都可实现
切入点表达式:知道对哪个类的哪个方法进行增强
execution([权限修饰符][返回类型][类全路径][方法名称][参数列表])
//execution(* com.empirefree.dao.BookDao.add(..)) //返回类型可以省略
//execution(* com.empirefree.dao.BookDao.*(..))
1、定义基本方法
2、创建增强类
3、进行通知的配置:@aspectj注解、xml中aspectj扫描
4、配置不同类型的通知
类似于引入了第三方技术包,和mybatis同级
1、编程式事务:类似代码try catch finally实现
2、声明式事务:使用配置实现事务管理(注解或者xml实现),内部是AOP原理
Spring事务管理API:
PlatformTransactionManager
事务传播行为:多事务之间是如果调用的,共7种,最常见的为REQUIRED, REQUIRED_NEW
脏读:一个未提交事务读到另一个未提交事务的数据
不可重复读:一个未提交事务读到另一个已提交事务中修改的数据
幻读:一个未提交事务读到另一个已提交事务中新增的数据
事务需要在一定时间内进行提交,不提交就回滚,默认-1, 时间单位是秒
事务需要在一定时间内进行提交,不提交就回滚,默认-1, 时间单位是秒
SpringWebFlux是响应式编程, 异步非阻塞,(异步非阻塞 Servlet3.1之后才支持), 内部核销是基于Reactor相关API实现
异步与同步针对调用者:A调用B,A发送请求后不等待B回复就做其他事情就是异步,等待B回复再做其他事情就是同步
阻塞与非阻塞针对被调用者:A调用B,B收到请求执行完给反馈就是阻塞,B收到请求后立刻反馈,然后再执行任务就是非阻塞
1、非阻塞:有限资源提高系统吞吐量
2、简化开发:采用函数式编程
1、两者都是采用注解,运行再Tomcat容器中
2、SpringMVC采用命令式编程(内部代码是一行一行执行),WebFlux采用异步响应式编程(适用于远程服务调用、网关这些)
一种面向数据流和变化传播的编程范式:类似于excel电子表格,A1,B1变化,相加而成的C1也要跟着变化。内部是采用Reactor实现
内部两个核心类Flux(返回N个元素实现发布者),Mono(返回0,或1个元素),可实现三种信号值:元素值,错误信号,完成信号(错误和完成都是终止信号,但错误信号可以传递错误信息,两者不能共存,若都没有,则表示无限信号流,若没有元素值,表示空数据流)
map: 元素转换成新元素
flatMap:元素转换成流在组合成新元素
与SpringMVC类似,内部有DispatchHandler控制器,该控制器实现WebHandler。
SpringWebFlux实现函数式编程用到了RouterFunction路由处理和HandlerFunction处理函数
(内部Netty使用了增强方法,属于异步非阻塞)
public Mono<Void> handle(ServerWebExchange exchange) {
return this.handlerMappings == null ? this.createNotFoundError() : Flux.fromIterable(this.handlerMappings).concatMap((mapping) -> {
return mapping.getHandler(exchange); //请求查询到处理方法
}).next().switchIfEmpty(this.createNotFoundError()).flatMap((handler) -> {
return this.invokeHandler(exchange, handler); //真正负责请求处理
}).flatMap((result) -> {
return this.handleResult(exchange, result); //结果响应
});
}
SpringMVC: 同步阻塞,基于SpringMVC + Servlet + Tomcat
SpringWebFlux: 异步非阻塞,基于SpringWebFlux + Reactor + Netty
使用ServerRequest、ServerResponse