面试速记之Spring

前言

本篇内容较繁杂,笔者会根据经验逐步浓缩,力求留下的都是精华。

IOC

降低耦合

把对象创建和对象调用交给Spring

关键点:xml解析、工厂模式、反射

演变过程:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
获取bean对象示例
在这里插入图片描述

bean有变化只需要修改配置文件信息就ok,代码部分无需修改

反射可以得到类的字节码文件(.class),从而获得类和对象

容器实现方式

ioc思想基于ioc容器(container)实现,它是对象工厂,容器实现的两种方式有:

1.BeanFactory(Spring内部接口,不推荐开发者使用)

2.ApplicationContext(是BeanFactory的子接口,提供更强大的功能给开发者使用)

对比

前者只加载了配置文件,后者还会创建好配置文件中的对象。

看上去第一种比较好(懒加载),但不可否认后者更加方便(程序初始化时就帮全部搞好了)

前者是读硬盘中路径下的xml,后者是读项目路径下的xml,理解为绝对路径和相对路径吧

bean管理

配置文件和注解方式

创建对象和注入属性

配置文件方式

常用属性
id:唯一标识
class:全限定类名

DI

ioc中注入属性的方式

通过setter方法或有参构造函数注入
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
p名称空间注入可以简化setter注入方式
在这里插入图片描述
设置空值和设置特殊符号的方式
在这里插入图片描述
在这里插入图片描述
外部bean注入示例
在这里插入图片描述
内部bean写法
在这里插入图片描述
外部bean级联赋值
在这里插入图片描述

在这里插入图片描述
注入集合类型:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
将集合单独抽取出来的以便复用:
在这里插入图片描述
注入数据源示例

第一种方式
在这里插入图片描述
第二种方式
可通过外部属性文件辅助装配
在这里插入图片描述
在这里插入图片描述
Spring提供自动装配

开启:使用bean标签的autowire属性,它有两个值byName和byType,分别是通过名称(id)注入和类型(class)注入

注解方式

对象创建

1.引入依赖
2.开启组件扫描(指定扫描范围)

<context:component-scan base-package="com.atguigu"></context:component-scan>

可自定义扫描内容:
在这里插入图片描述
3.创建类,在类上添加创建对象注解
Spring提供的注解:
@Component
@Service
@Controller
@Repository
上面四个注解功能一致,都可以用来创建bean实例(默认名称为对应类的首字母小写,可通过设置注解的value值自定义名称)

属性注入

@Autowired:根据属性类型进行自动装配
@Qualifier:根据属性名称进行注入(配合@Autowired使用,适用于有多个实现类的情况)
在这里插入图片描述

@Resource:可以根据类型注入,也可以根据名称注入
在这里插入图片描述

@Vaule:注入普通类型属性
在这里插入图片描述

完全注解开发

配置类代替配置文件(用@Configuration标识配置类)
在这里插入图片描述
与xml差异对比
在这里插入图片描述

Spring中bean类型

1.普通bean
2.工厂bean

关键区别在于定义的bean的类型与实际拿到的类型是否一致

比如定义Book类只能拿到Book类对象,而定义BookFactory类能够拿到Book类的对象

bean的作用域

在Spring中可设置创建的bean是单实例还是多实例

默认是单例的

验证:
在这里插入图片描述

通过设置bean标签的scope属性设置实例数量:
singleton:单例,每次从容器拿都是同一个
prototype:原型,每次从容器拿都是新的
request:一个request一个实例
session:一个session一个实例
global session

前两个属性值的细微区别:
前者在加载xml文件时就会创建单例对象
后者是在调用getBean()方法的时候才创建实例对象(每调一次会创建一个新的)

bean的生命周期

生命周期定义:创建->销毁

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

2.为bean的属性设置值和对其他bean的引用(调用setter方法)

3.调用bean的初始化方法
需在bean标签中设置init-method属性值为指定方法名

4.bean可以使用了

5.当容器关闭的时候,调用bean的销毁方法
需在bean标签中设置 destroy-method属性值为指定方法名,该方法中应包含context.close()方法

⚠️注意:如果加上了bean的后置处理器(实现BeanPostProcessor接口)
在这里插入图片描述
那么bean的生命周期应该有七步,在初始化(第3步)的前后会把bean的实例传给bean后置处理器的方法

AOP

面向切面编程,是一种编程思想

降低耦合度,提高可重用性

不通过修改源代码的方式,在主干功能中添加新的功能
在这里插入图片描述

动态代理

https://blog.csdn.net/w372426096/article/details/82659354,多读读这篇文章,会有新的收获

jdk——需要接口

懵逼了可以去看看P27,https://www.bilibili.com/video/BV1Vf4y127N5?p=27&spm_id_from=pageDriver
在这里插入图片描述

说白了就是:现在有个接口,接口有个实现类,有一个我们自己定义的代理类(实现了InvocationHandler接口,重写了invoke方法),将接口实现类传到自定义的代理类中,让代理类去增强实现类中指定的方法。(要告诉代理类是哪个方法,使用了哪个实现类)
在这里插入图片描述
在这里插入图片描述

cglib——无需接口

在这里插入图片描述
在这里插入图片描述
AspectJ是一个aop框架,可通过注解和配置文件工作

当有接口,有目标类的时候,aspectJ使用的是jdk的动态代理,当只有目标类,没有接口,使用的是cglib动态代理。

术语

1.连接点:理论上可以被增强的方法

2.切入点:实际上真正被增强的方法

3.通知(增强):增强的内容
环绕通知 Around
前置通知 Before
最终通知 After
后置(返回)通知 AfterReturning
异常通知 AfterThrowing
执行顺序
无异常情况:Around->Before->自己的method->Around->After->AfterReturning
异常情况:Around->Before->自己的method->Around->After->AfterThrowing
可见后置和异常两者不能共存

4.切面(它是一个动作,把通知应用到切入点的过程)

切入点

在这里插入图片描述
抽取切入点,以便复用
在这里插入图片描述

在这里插入图片描述

其他

在这里插入图片描述
aop使用到了责任链模式
https://www.runoob.com/design-pattern/chain-of-responsibility-pattern.html
在这里插入图片描述
在这里插入图片描述

为什么每次都要回到链上呢?
因为每次链上的元素会重新排序(chain的元素顺序是基于拓扑排序的),所以得回去获取到新排序后的对应通知对象

事务

在这里插入图片描述

Spring中有两种事务

编程式事务管理(不推荐)

声明式事务管理(底层是AOP)
可用注解(常用)或 xml 配置

Spring事务管理API——事务管理器
在这里插入图片描述
在这里插入图片描述

Spring事务传播行为

事务方法:能够改变数据库数据的操作

七种传播行为的前两种要记住

required
当前有事务?加入它;当前无事务?启动一个新的事务并加入

required_new
启动一个新的事务并加入,如果已经有旧的事务将它挂起
在这里插入图片描述
在这里插入图片描述

隔离级别

用于并发,隔离性(多事务间不产生影响)

脏读

一个未提交事务A读取到了另一个未提交事务B的数据,一旦事务B回滚,那么A持有的B的数据就成了脏数据。
在这里插入图片描述

不可重复读

一个未提交事务读取到了另一提交事务修改的数据
在这里插入图片描述

幻读/虚读

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

通过设置事务的隔离级别,可以解决上述问题
在这里插入图片描述

可在@Transactional标签中设置isolation属性

待看:https://www.bilibili.com/video/BV1KC4y1t7x4?from=search&seid=2975270978271107013

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值