Skip to content

Commit fedfce7

Browse files
committed
spring.md
1 parent 55e9836 commit fedfce7

File tree

1 file changed

+310
-0
lines changed

1 file changed

+310
-0
lines changed

spring.md

Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
### 简单描述bean的生命周期?
2+
3+
> 生命周期流程图
4+
5+
![image-20220308123507613](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220308123507613.png)
6+
7+
> 通过getBean()方法获取Bean
8+
9+
![image-20220309181117293](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309181117293.png)
10+
11+
![image-20220309181237075](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309181237075.png)
12+
13+
![image-20220309181328903](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309181328903.png)
14+
15+
> 调用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法
16+
17+
![image-20220309181653695](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309181653695.png)
18+
19+
![image-20220309181733406](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309181733406.png)
20+
21+
![image-20220309181756529](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309181756529.png)
22+
23+
> 实例化对象调用对象的构造函数
24+
25+
![image-20220309181910990](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309181910990.png)
26+
27+
![image-20220309181946415](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309181946415.png)
28+
29+
![image-20220309182015374](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309182015374.png)
30+
31+
> 调用 InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法
32+
33+
![image-20220309182233335](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309182233335.png)
34+
35+
![image-20220309182459381](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309182459381.png)
36+
37+
> 调用InstantiationAwareBeanPostProcessor的postProcessProperties
38+
39+
![image-20220309184414643](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309184414643.png)
40+
41+
> 调用InstantiationAwareBeanPostProcessor的postProcessPropertyValues
42+
43+
![image-20220309184520052](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309184520052.png)
44+
45+
> 设置属性值
46+
47+
48+
49+
> 初始化Bean
50+
51+
![image-20220309184652448](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309184652448.png)
52+
53+
> 调用Aware接口
54+
55+
![image-20220309184803765](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309184803765.png)
56+
57+
![image-20220309184832329](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309184832329.png)
58+
59+
> 调用BeanPostProcessor的postProcessBeforeInitialization方法
60+
61+
![image-20220309185003381](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309185003381.png)
62+
63+
![image-20220309185033736](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309185033736.png)
64+
65+
> 调用InitializingBean的afterPropertiesSet方法
66+
67+
![image-20220309185158715](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309185158715.png)
68+
69+
![image-20220309185335754](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309185335754.png)
70+
71+
> 调用init-method方法
72+
73+
![image-20220309185436286](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309185436286.png)
74+
75+
> 调用BeanPostProcessor的postProcessAfterInitialization方法
76+
77+
![image-20220309185545439](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309185545439.png)
78+
79+
![image-20220309185609299](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220309185609299.png)
80+
81+
82+
83+
84+
85+
86+
87+
Spring容器帮助我们去管理对象,从对象的产生到销毁的环节都是由容器进行控制,其中主要包含实例化和初始化两个关键环节,当然在整个过程中会有一些扩展点。下面来详细描述下各个环节和步骤。
88+
89+
> 1. 实例化bean对象通过反射的方式来生成
90+
91+
在源码中有一个createBeanInstance的方法是专门来生成对象的
92+
93+
> 2. 当bean对象创建完成后,对象的属性值都是默认值,所以需要开始给bean填充属性,通过populateBean方法来完成对象属性的填充,期间会涉及到循环依赖的问题
94+
95+
> 3. 向bean对象中设置容器属性,会调用invokeAwareMethods方法来将容器对象设置到具体的bean对象中去
96+
97+
如:applicationContext、BeanFactory、Enviroment、ResourceLoader
98+
99+
BeanFactoryAware、ApplicationContextAware
100+
101+
> 4. 调用BeanPostProcessor中的前置处理方法来进行Bean对象的扩展工作,ApplicationContextPostProcessor
102+
103+
> 5. 调用InvokeinitMethods方法来完成初始化方法的调用,在此方法过程中,需要判断当前bean对象是否实现了initializingBean的接口,如果实现了调用afterPropertiesSet方法来最后设置Bean对象
104+
105+
> 6. 调用BeanPostProcessor的后置处理方法,完成对Bean对象的后置处理工作,AOP就是在此处实现的,实现的接口实现名字叫做AbstractAutoProxyCreator
106+
107+
> 7. 获取到完整对象,通过getBean的方式去进行对象的获取和使用
108+
109+
> 8. 当对象使用完成之后,容器在关闭的时候会销毁对象,首先会去判断是否实现了DisposableBean接口,然后去调用destroyMethod方法
110+
111+
### BeanFactroy和FactoryBean的区别
112+
113+
![image-20220308130015389](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220308130015389.png)
114+
115+
BeanFactory和FactoryBean都可以用来创建对象,只不过创建的流程和方式不同。
116+
当使用BeanFactory的时候必须要严格的遵守 Bean 的生命周期,经过一系列繁杂的步骤之后才可以创建单例对象,是流水线式的创建过程。
117+
而FactoryBean是用户可以自定义bean对象的创建流程,不需要按照Bean的生命周期来创建,在此接口中包含了三个方法
118+
getObject();// 获取对象
119+
getObjectType();// 获取对象类型
120+
isSingleton();// 判断是否是单例对象
121+
122+
![image-20220308130328993](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220308130328993.png)
123+
124+
如:Mybatis中的SqlSessionFactoryBean
125+
126+
![image-20220308130650858](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220308130650858.png)
127+
128+
### Spring中使用的设计模式
129+
130+
> 1. 单例模式
131+
132+
Spring 中的bean都是单例的
133+
134+
> 2. 工厂模式
135+
136+
BeanFactroy
137+
138+
> 3. 模板模式
139+
140+
postProcessorBeanFatory
141+
142+
onRefresh
143+
144+
> 4. 观察者模式
145+
146+
listener,event,multicast
147+
148+
> 5. 适配器模式
149+
150+
Adapter
151+
152+
> 6. 装饰者模式
153+
154+
BeanWrapper
155+
156+
> 7. 责任链模式
157+
158+
使用Aop的时候会有一个责任链模式
159+
160+
> 8. 代理模式
161+
162+
Aop中动态代理
163+
164+
> 9. 委托者模式
165+
166+
delegate
167+
168+
> 10. 建造者模式
169+
170+
SpringApplicationBuilder
171+
172+
> 11. 策略模式
173+
174+
XmlBeanDefinitonReader、 PropertiesBeanDefinitionReader
175+
176+
177+
178+
### ApplicationContext和BeanFactroy的区别
179+
180+
BeanFactory是访问Spring容器的根接口、里面只是提供了某些基本方法的约束和规范,为了满足更多需要,ApplicationContext实现了BeanFactory接口,并在此接口的基础上做了某些扩展功能提供了更加丰富的API
181+
182+
![image-20220308132144014](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220308132144014.png)
183+
184+
![image-20220308132330690](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220308132330690.png)
185+
186+
### 谈谈你对循环依赖的理解
187+
188+
> 1. 什么是循环依赖
189+
190+
A 依赖 B B 依赖 A
191+
192+
![image-20220308132624010](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220308132624010.png)
193+
194+
> 2. Spring中Bean对象的创建都要经历实例化和初始化(属性填充.)的过程
195+
196+
![image-20220308133055628](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220308133055628.png)
197+
198+
![image-20220308133804174](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220308133804174.png)
199+
200+
> 3. 只有一级缓存是否可行? 不可以
201+
202+
会把成品状态的Bean 对象和半成品状态的Bean对象放到一起,而半成品对象是无法暴露给外部使用的,所以要将成品和半成品分开存储,一级缓存()中放置成品对象,二级缓存()放置半成品对象
203+
204+
> 4. 只有二级缓存是否可行? 不可以
205+
206+
如果整个应用程序中不涉及到AOP,那么二级缓存是足以解决循环依赖的问题,如果AOP中存在了循环依赖,那么必须要用三级缓存才能解决
207+
208+
> 5. 为什么需要三级缓存
209+
210+
![image-20220308134528654](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220308134528654.png)
211+
212+
三级缓存的Value类型是ObjectFactroy,是一个函数式接口,不是直接进行调用,只有在调用getObject方法的时候才会去调用里面存储的lamda表达式,存在的意义是保证在整个容器运行过程中同名的bean对象只能有一个
213+
214+
> 如果一个对象被代理,或者说需要生成代理对象,那么是否需要先生成一个原始对象?要的
215+
216+
> 当创建出代理对象之后,会同时存在代理对象和普通对象,那么此时我该用哪一个?
217+
218+
当需要代理对象的时候,或者说代理对象生成的时候必须要覆盖原始对象,也就是说,整个容器中一个bean名称仅有一个bean
219+
220+
在实际调用的过程中,是没有办法确定什么时候对象需要被调用,因此当一个对象被调用的时候,优先判断当前对象是否需要被代理,类似于回调机制,当获取对象之后根据传入的lamda表达式来确认返回的是哪一个确定的对象
221+
222+
如果条件符合返回代理对象、如果条件不符合返回原始对象
223+
224+
![image-20220308140522149](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220308140522149.png)
225+
226+
![image-20220308140453763](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220308140453763.png)
227+
228+
![image-20220308140432897](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220308140432897.png)
229+
230+
231+
232+
### Spring Aop 底层实现
233+
234+
动态代理
235+
236+
aop是ioc的一个扩展功能,先有的ioc,在有的aop,只是在ioc的整个流程中新增的一个扩展点而已:BeanPostProcessor:
237+
238+
bean的创建过程中有一个步骤可以对bean进行扩展实现,aop本身就是一个扩展功能,所以在BeanPostProcessor的后置处理方法中来实现
239+
240+
> 1. 代理对象的创建过程(advice,切面,切点)
241+
242+
> 2. 通过JDK或者CGlib的方式来生成代理对象
243+
244+
> 3. 在执行方法调用的时候,会调用到生成的字节码文件中,直接会找到 DynamicAdvisoredInterceptor类中的intercept方法,从此方法开始执行
245+
246+
> 4. 根据之前定义好的通知来生成拦截器链
247+
248+
> 5. 从拦截器链中依次获取每一个通知开始进行执行,在执行过程中,为了方便找到下一个通知是哪个,会有一个CglibMethodInvocation的对象,找的时候是从-1的位置依次开始查找并执行的
249+
250+
251+
252+
### Spring的事务是如何回滚的
253+
254+
Spring的事务管理是如何实现的?
255+
256+
总:spring的事务是由aop来实现的,首先要生成具体的代理对象,然后按照aop整套流程来执行具体的操作逻辑,正常情况下要通过通知来完成核心功能,但是事务不是通过通知来实现的,而是通过一个TransactionInterceptor来实现的,然后调用invoke来实现具体的逻辑
257+
258+
分:
259+
260+
> 1. 先做准备工作,解析各个方法上事务相关的属性,根据具体的属性来判断是否开启新事务
261+
262+
> 2. 当需要开启的时候,获取数据库连接,关闭自动提交功能,开启事务
263+
264+
> 3. 执行具体的Sql逻辑操作
265+
266+
> 4. 在操作过程中如果执行失败了,那么会通过completTransactionAfterThrowing来完成事务的回滚操作,回滚的具体逻辑是通过doRollBack方法来实现的,实现的时候也是先获取连接对象
267+
268+
> 5. 如果执行正常,则通过commitTransactionAfterReturning来提交事务,提交的具体逻辑是通过doCommit方法来实现的
269+
270+
> 6. 当事务执行完毕后需要清除相关的事务信息cleanupTransactionInfo,如果更细致的话需要知道TransactionInfo,TransactionStatus
271+
272+
![image-20220308163759569](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220308163759569.png)
273+
274+
275+
276+
### Spring事务传播机制
277+
278+
![image-20220308165708466](C:\Users\52606\AppData\Roaming\Typora\typora-user-images\image-20220308165708466.png)
279+
280+
> Required:当前有事务则加入,没事务则新建
281+
282+
> Supports:当前有事务则加入,没事务则不通过事务
283+
284+
> Mandatory:当前有事务则加入,没事务抛异常
285+
286+
> Requires_New:新建一个事务
287+
288+
> Not_Support:不通过事务的方式运行
289+
290+
> Never:不通过事务的方式运行,当前有事务则抛异常
291+
292+
> Nested:
293+
294+
某一个事务嵌套另一个事务的时候怎么办?
295+
296+
A 方法调用 B 方法 AB都有事务,但传播特性不同,那么如果A有异常 B 怎么办,B有异常A怎么办
297+
298+
总:事务的船舶特性指的是不同方法的嵌套调用过程中,事务应该如何进行处理,是用同一个事务还是不同的事务,当出现异常的时候是回滚还是提交,两个方法之间的相关影响,在日常工作中 使用的比较多的是Required、Require_New, Nested
299+
300+
分:
301+
302+
1. 先说事务的不同分类,可以分为三类:支持当前事务,不支持当前事务,嵌套事务
303+
2. 如果外层方法是Required 内层方法是 Required、Require_New, Nested
304+
3. 如果外层方法是Require_New 内层方法是 Required、Require_New, Nested
305+
4. 如果外层方法是Nested内层方法是 Required、Require_New, Nested
306+
307+
308+
309+
310+

0 commit comments

Comments
 (0)