spring_复习_IOC

1.为什么使用IOC?什么是IOC?什么是DI?

IOC (inversion of control)中文为控制反转。

IOC是一种设计、设计模式。DI(dependency injection)依赖注入是注入的一种方式。

一般依赖使用:

一般依赖使用方法

1
2
3
Student student = new Student();
Score score = new Score();
student.setScore(score);

IOC容器简单说明

降低了程序里对象与对象之间的耦合性。

容器自动把依赖对象注入目标 Bean,三种注入方式:

构造器注入【推荐】:构造方法传参,保证对象创建完成依赖就绪,不可变对象优先。
Setter 注入:setXxx(),适合可选依赖

字段注入 @Autowired 直接写在属性上

字段注入缺点:无法 final、难以单元测试、与容器强耦合,Spring 官方不推荐

2.spring ioc 的源码分析及实现

首先先明确几个概念:

Environment 环境,用于获取系统环境及系统配置的对象

post processor 称后置处理器或增强器,就是对类进制扩展,用反射beanFactoryPostProcessor是对bean工厂进行增强,beanPostProcessor是对bean进行增强。

aware 意识、察觉 继承aware后可以获取对应的aware的属性值,spring 初始化时会调用设置。

BeanDefinitionReader 根据xml 或 注解解析成 beanDefinition的抽象接口

beanDefinition是xml 或 注解 里定义的bean结构的对象

listener 监听器

envent 事件

Multicast 多播器

spring ioc创建对象流程(对象生命周期)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
1.创建项目时会指定使用啥方式配置spring, 比如 xml 或 注解

2.加载配置文件

3.生成beanDefinition并注册到容器

4.BeanFactoryPostProcessor的执行(【Bean定义加载完成,Bean实例化之前】执行,修改BeanDefinition)

5.根据反射实例化bean对象

6.初始化bean对象

6.1 填充属性(依赖注入)

6.2 执行 BeanNameAware#setBeanName

6.3 执行 BeanFactoryAware#setBeanFactory

6.3 执行 Bean后置处理器BeanPostProcessor.beforeInitialization

6.4 初始化方法:
@PostConstruct
InitializingBean#afterPropertiesSet()
xml init-method / @Bean(initMethod="xxx")

6.5 执行 Bean后置处理器BeanPostProcessor.afterInitialization(AOP 代理在这里生成!)

这时bean对象是完整的

7.点击 程序停止 -> 容器销毁
@PreDestroy
DisposableBean#destroy()
destroy-method

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class UserService implements BeanNameAware, BeanFactoryAware, ApplicationContextAware,
InitializingBean, DisposableBean {

private String name;

public UserService() {
System.out.println("【1】UserService 构造方法,实例化");
}

public void setName(String name) {
System.out.println("【2】setName 属性赋值(依赖注入)");
this.name = name;
}

// ===================== Aware 回调 =====================
@Override
public void setBeanName(String name) {
System.out.println("【3-Aware】BeanNameAware → bean名称:" + name);
}

@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("【3-Aware】BeanFactoryAware 注入BeanFactory");
}

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("【3-Aware】ApplicationContextAware 注入上下文");
}

// ===================== 初始化阶段 =====================
@PostConstruct
public void postConstruct() {
System.out.println("【5】@PostConstruct 注解方法");
}

@Override
public void afterPropertiesSet() throws Exception {
System.out.println("【6】InitializingBean afterPropertiesSet");
}

// xml/@Bean 指定的自定义init方法
public void customInit() {
System.out.println("【7】自定义 init-method");
}

// ===================== 销毁阶段 =====================
@PreDestroy
public void preDestroy() {
System.out.println("【9】@PreDestroy");
}

@Override
public void destroy() throws Exception {
System.out.println("【10】DisposableBean destroy()");
}

// xml/@Bean 指定自定义销毁方法
public void customDestroy() {
System.out.println("【11】自定义 destroy-method");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// Aware执行完之后,初始化方法之前执行
if(bean instanceof UserService){
System.out.println("【4】BeanPostProcessor beforeInitialization");
}
return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// 所有初始化逻辑完成之后执行;AOP代理就是在这里生成!
if(bean instanceof UserService){
System.out.println("【8】BeanPostProcessor afterInitialization");
}
return bean;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// Aware执行完之后,初始化方法之前执行
if(bean instanceof UserService){
System.out.println("【4】BeanPostProcessor beforeInitialization");
}
return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// 所有初始化逻辑完成之后执行;AOP代理就是在这里生成!
if(bean instanceof UserService){
System.out.println("【8】BeanPostProcessor afterInitialization");
}
return bean;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.demo")
public class SpringConfig {

@Bean(initMethod = "customInit", destroyMethod = "customDestroy")
public UserService userService(){
UserService userService = new UserService();
userService.setName("test");
return userService;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestBeanLifeCycle {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
System.out.println("==== IOC容器启动完成,Bean就绪 ====");

UserService userService = ctx.getBean(UserService.class);
System.out.println("获取Bean完成:" + userService);

// 关闭容器,触发销毁流程
ctx.close();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
【1】UserService 构造方法,实例化
【2】setName 属性赋值(依赖注入)
【3-Aware】BeanNameAware → bean名称:userService
【3-Aware】BeanFactoryAware 注入BeanFactory
【3-Aware】ApplicationContextAware 注入上下文
【4】BeanPostProcessor beforeInitialization
【5】@PostConstruct 注解方法
【6】InitializingBean afterPropertiesSet
【7】自定义 init-method
【8】BeanPostProcessor afterInitialization
==== IOC容器启动完成,Bean就绪 ====
获取Bean完成:com.demo.UserService@xxxx
【9】@PreDestroy
【10】DisposableBean destroy()
【11】自定义 destroy-method

Aware 作用

让 Bean 感知 Spring 容器底层组件,获取容器内部对象(BeanFactory、ApplicationContext、BeanName)

开发规范:尽量少用 Aware,强耦合 Spring 框架;优先依赖注入。

BeanPostProcessor 关键知识点

  1. 作用时机:初始化前后
  2. 属于容器扩展点,作用于所有 Bean
  3. Spring AOP 核心实现:AnnotationAwareAspectJAutoProxyCreator 就是一个 BeanPostProcessor,在postProcessAfterInitialization创建代理对象。
  4. 如果在这里返回新对象,可以替换原始 Bean。

三种初始化方式优先级

@PostConstruct > InitializingBean > init-method

三种销毁优先级

@PreDestroy > DisposableBean > destroy-method

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
/**
* 做容器刷新前的准备工作
* 1、设置容器的启动时间
* 2、设置活跃状态为true
* 3、设置关闭状态为false
* 4、获取Environment对象,并加载当前系统的属性值到Environment对象中
* 5、准备监听器和事件的集合对象,默认为空的集合
*/

prepareRefresh();

// Tell the subclass to refresh the internal bean factory.
// 创建容器对象:DefaultListableBeanFactory
// 加载xml配置文件的属性值到当前工厂中,最重要的就是BeanDefinition
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// Prepare the bean factory for use in this context.
// beanFactory的准备工作,对各种属性进行填充
prepareBeanFactory(beanFactory);

try {
// Allows post-processing of the bean factory in context subclasses.
// 子类覆盖方法做额外的处理,此处我们自己一般不做任何扩展工作,但是可以查看web中的代码,是有具体实现的
postProcessBeanFactory(beanFactory);

// Invoke factory processors registered as beans in the context.
// 调用各种beanFactory处理器
invokeBeanFactoryPostProcessors(beanFactory);

// Register bean processors that intercept bean creation.
// 注册bean处理器,这里只是注册功能,真正调用的是getBean方法
registerBeanPostProcessors(beanFactory);

// Initialize message source for this context.
// 为上下文初始化message源,即不同语言的消息体,国际化处理,在springmvc的时候通过国际化的代码重点讲
initMessageSource();

// Initialize event multicaster for this context.
// 初始化事件监听多路广播器
initApplicationEventMulticaster();

// Initialize other special beans in specific context subclasses.
// 留给子类来初始化其他的bean
onRefresh();

// Check for listener beans and register them.
// 在所有注册的bean中查找listener bean,注册到消息广播器中
registerListeners();

// Instantiate all remaining (non-lazy-init) singletons.
// 初始化剩下的单实例(非懒加载的)
finishBeanFactoryInitialization(beanFactory);

// Last step: publish corresponding event.
// 完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
finishRefresh();
}

catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}

// Destroy already created singletons to avoid dangling resources.
// 为防止bean资源占用,在异常处理中,销毁已经在前面过程中生成的单件bean
destroyBeans();

// Reset 'active' flag.
// 重置active标志
cancelRefresh(ex);

// Propagate exception to caller.
throw ex;
}

finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// 为上下文初始化类型转换器
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}

// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
// 如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器,主要用于注解属性值的解析
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}

// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
// 尽早初始化loadTimeWeaverAware bean,以便尽早注册它们的转换器
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}

// Stop using the temporary ClassLoader for type matching.
// 禁止使用临时类加载器进行类型匹配
beanFactory.setTempClassLoader(null);

// Allow for caching all bean definition metadata, not expecting further changes.
// 冻结所有的bean定义,说明注册的bean定义将不被修改或任何进一步的处理
beanFactory.freezeConfiguration();

// Instantiate all remaining (non-lazy-init) singletons.
// 实例化剩下的单例对象
beanFactory.preInstantiateSingletons();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}

// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}

// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {

/**
* 提取对应的beanName,很多同学可能会认为此处直接使用即可,为什么还要进行转换呢,原因在于当bean对象实现FactoryBean接口之后就会变成&beanName,同时如果存在别名,也需要把别名进行转换*/
String beanName = transformedBeanName(name);
Object bean;

// Eagerly check singleton cache for manually registered singletons.
/**提前检查单例缓存中是否有手动注册的单例对象,跟循环依赖有关联*/
Object sharedInstance = getSingleton(beanName);
// 如果bean的单例对象找到了,且没有创建bean实例时要使用的参数
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 返回对象的实例,很多同学会理解不了这句话存在的意义,当你实现了FactoryBean接口的对象,需要获取具体的对象的时候就需要此方法来进行获取了
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}

else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// 当对象都是单例的时候会尝试解决循环依赖的问题,但是原型模式下如果存在循环依赖的情况,那么直接抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}

// Check if bean definition exists in this factory.
// 如果bean定义不存在,就检查父工厂是否有
BeanFactory parentBeanFactory = getParentBeanFactory();
// 如果beanDefinitionMap中也就是在所有已经加载的类中不包含beanName,那么就尝试从父容器中获取
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
// 获取name对应的规范名称【全类名】,如果name前面有'&',则会返回'&'+规范名称【全类名】
String nameToLookup = originalBeanName(name);
// 如果父工厂是AbstractBeanFactory的实例
if (parentBeanFactory instanceof AbstractBeanFactory) {
// 调用父工厂的doGetBean方法,就是该方法。【递归】
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
// 如果有创建bean实例时要使用的参数
// Delegation to parent with explicit args. 使用显示参数委派给父工厂
// 使用父工厂获取该bean对象,通bean全类名和创建bean实例时要使用的参数
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
// 没有创建bean实例时要使用的参数 -> 委托给标准的getBean方法。
// 使用父工厂获取该bean对象,通bean全类名和所需的bean类型
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
// 使用父工厂获取bean,通过bean全类名
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
// 如果不是做类型检查,那么表示要创建bean,此处在集合中做一个记录
if (!typeCheckOnly) {
// 为beanName标记为已经创建(或将要创建)
markBeanAsCreated(beanName);
}

try {
// 此处做了BeanDefinition对象的转换,当我们从xml文件中加载beandefinition对象的时候,封装的对象是GenericBeanDefinition,
// 此处要做类型转换,如果是子类bean的话,会合并父类的相关属性
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 检查mbd的合法性,不合格会引发验证异常
checkMergedBeanDefinition(mbd, beanName, args);

// Guarantee initialization of beans that the current bean depends on.
// 如果存在依赖的bean的话,那么则优先实例化依赖的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 如果存在依赖,则需要递归实例化依赖的bean
for (String dep : dependsOn) {
// 如果beanName已注册依赖于dependentBeanName的关系
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 注册各个bean的依赖关系,方便进行销毁
registerDependentBean(dep, beanName);
try {
// 递归优先实例化被依赖的Bean
getBean(dep);
}
// 捕捉为找到BeanDefinition异常:'beanName'依赖于缺少的bean'dep'
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}

// Create bean instance.
// 创建bean的实例对象
if (mbd.isSingleton()) {
// 返回以beanName的(原始)单例对象,如果尚未注册,则使用singletonFactory创建并注册一个对象:
sharedInstance = getSingleton(beanName, () -> {
try {
// 为给定的合并后BeanDefinition(和参数)创建一个bean实例
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
// 显示地从单例缓存中删除实例:它可能是由创建过程急切地放在那里,以允许循环引用解析。还要删除
// 接收到该Bean临时引用的任何Bean
// 销毁给定的bean。如果找到相应的一次性Bean实例,则委托给destoryBean
destroySingleton(beanName);
// 重新抛出ex
throw ex;
}
});
// 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是
// FactoryBean会直接返回beanInstance实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 原型模式的bean对象创建
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
// 它是一个原型 -> 创建一个新实例
// 定义prototype实例
Object prototypeInstance = null;
try {
// 创建Prototype对象前的准备工作,默认实现将beanName添加到prototypesCurrentlyInCreation中
beforePrototypeCreation(beanName);
// 为mbd(和参数)创建一个bean实例
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 创建完prototype实例后的回调,默认是将beanName从prototypesCurrentlyInCreation移除
afterPrototypeCreation(beanName);
}
// 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是
// FactoryBean会直接返回beanInstance实例
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}

else {
// 指定的scope上实例化bean
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
// 从scopes中获取scopeName对于的Scope对象
Scope scope = this.scopes.get(scopeName);
// 如果scope为null
if (scope == null) {
// 抛出非法状态异常:没有名为'scopeName'的scope注册
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
// 从scope中获取beanName对应的实例对象
Object scopedInstance = scope.get(beanName, () -> {
// 创建Prototype对象前的准备工作,默认实现 将beanName添加到prototypesCurrentlyInCreation中
beforePrototypeCreation(beanName);
try {
// 为mbd(和参数)创建一个bean实例
return createBean(beanName, mbd, args);
}
finally {
// 创建完prototype实例后的回调,默认是将beanName从prototypesCurrentlyInCreation移除
afterPrototypeCreation(beanName);
}
});
// 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是
// FactoryBean会直接返回beanInstance实例
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
// 捕捉非法状态异常
// 抛出Bean创建异常:作用域 'scopeName' 对于当前线程是不活动的;如果您打算从单个实例引用它,请考虑为此
// beanDefinition一个作用域代理
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
// 捕捉获取Bean对象抛出的Bean异常
// 在Bean创建失败后,对缓存的元数据执行适当的清理
cleanupAfterBeanCreationFailure(beanName);
// 重新抛出ex
throw ex;
}
}

// Check if required type matches the type of the actual bean instance.
// 检查requiredType是否与实际Bean实例的类型匹配
// 如果requiredType不为null&&bean不是requiredType的实例
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
// 获取此BeanFactory使用的类型转换器,将bean转换为requiredType
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
// 如果convertedBean为null
if (convertedBean == null) {
// 抛出Bean不是必要类型的异常
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
// 返回convertedBean
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
// 将bean返回出去
return (T) bean;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Quick check for existing instance without full singleton lock
// 从单例对象缓存中获取beanName对应的单例对象
Object singletonObject = this.singletonObjects.get(beanName);
// 如果单例对象缓存中没有,并且该beanName对应的单例bean正在创建中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//从早期单例对象缓存中获取单例对象(之所称成为早期单例对象,是因为earlySingletonObjects里
// 的对象的都是通过提前曝光的ObjectFactory创建出来的,还未进行属性填充等操作)
singletonObject = this.earlySingletonObjects.get(beanName);
// 如果在早期单例对象缓存中也没有,并且允许创建早期单例对象引用
if (singletonObject == null && allowEarlyReference) {
// 如果为空,则锁定全局变量并进行处理
synchronized (this.singletonObjects) {
// Consistent creation of early reference within full singleton lock
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
// 当某些方法需要提前初始化的时候则会调用addSingletonFactory方法将对应的ObjectFactory初始化策略存储在singletonFactories
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 如果存在单例对象工厂,则通过工厂创建一个单例对象
singletonObject = singletonFactory.getObject();
// 记录在缓存中,二级缓存和三级缓存的对象不能同时存在
this.earlySingletonObjects.put(beanName, singletonObject);
// 从三级缓存中移除
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}

循环依赖

问题:A 依赖 B,B 依赖 A

  • prototype:无法解决,直接报错
  • singleton:Spring 支持setter 注入循环依赖,三级缓存解决

三级缓存

  1. 一级缓存 singletonObjects:完整就绪单例 Bean
  2. 二级缓存 earlySingletonObjects:提前暴露半成品 Bean(已经实例化,未完成属性注入)
  3. 三级缓存 singletonFactories:Bean 工厂 ObjectFactory,用来生成早期代理对象

A 实例化 → 放入三级缓存 → 填充属性发现需要 B
B 实例化 → 放入三级缓存 → 填充属性需要 A
去三级缓存取出 A 的工厂,获取半成品 A 放入二级缓存,B 完成创建放入一级缓存
A 继续完成属性填充,最终移入一级缓存

构造器注入循环依赖:无法解决,因为实例化阶段就需要依赖,没有机会存入三级缓存

不能解决循环依赖:

1.通过构造器注入的不能解决

2.非单例的不能解决

循环依赖

三级缓存能不能删掉二级缓存?为什么?

不能删除二级缓存 earlySingletonObjects

  1. 一级:singletonObjects 完整成品 Bean
  2. 二级:earlySingletonObjects 半成品 Bean(提前暴露)
  3. 三级:singletonFactories ObjectFactory(用于生成代理对象)

场景:存在多个 Bean 同时循环依赖同一个 Bean A,且 A 需要 AOP 代理

  1. B 获取 A:从三级缓存执行 ObjectFactory,生成代理 A,移入二级缓存
  2. C 也同时需要 A
    如果没有二级缓存,每次获取都会再次执行 ObjectFactory,重复创建多个代理对象

二级缓存作用:
保证一个半成品 Bean只生成一次代理,复用同一个代理实例,避免多次创建代理对象,提升性能、保证单例唯一性。

精简背诵版:
二级缓存用来缓存已经从三级工厂生成好的早期代理 Bean,防止多个依赖重复调用工厂重复创建代理。


spring_复习_IOC
http://hanqichuan.com/2019/09/03/java框架与工具/spring/spring_复习_IOC/
作者
韩启川
发布于
2019年9月3日
许可协议