前言

本文主要研究如何从IOC容器已有的BeanDefinition信息,实例化出Bean对象。
这里还会包括三块重点内容:

  1. BeanFactory中getBean的主体思路
  2. Spring如何解决循环依赖问题
  3. Spring中Bean的生命周期

一、BeanFactory中getBean的主体思路

我们知道BeanFactory定义了Bean容器的规范,其中包含根据bean的名字、Class类型和参数等来得到bean实例。

1
2
3
4
5
6
// 根据bean的名字和Class类型等来得到bean实例    
Object getBean(String name) throws BeansException;
Object getBean(String name, Class requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

研究源码之前的初步思考

了解过IoC容器初始化的流程,最终将Bean的定义即BeanDefinition放到beanDefinitionMap中,本质上是一个ConcurrentHashMap<String, Object>,并且BeanDefinition接口中包含了这个类的Class信息以及是否是单例等。
BeanDefinition属性

这样我们初步有了实现Object getBean(String name)这个方法的思路:

  1. beanDefinitionMap通过beanName获得BeanDefinition
  2. BeanDefinition中获得beanClassName
  3. 通过反射初始化beanClassName的实例instance
    • 构造函数BeanDefinition的**getConstructorArgumentValues()**方法获取
    • 属性值BeanDefinition的**getPropertyValues()**方法获取
  4. 返回beanName的实例instance
  5. 由于BeanDefinition还有单例的信息,如果是无参构造函数的实例还可以放在一个缓存中,这样下次获取这个单例的实例时只需要从缓存中获取,如果获取不到再通过上述步骤获取。

(PS:如上只是我们初步的思路,而Spring还需要考虑各种设计上的问题,比如beanDefinition中其它定义,循环依赖等;所以来看下Spring是如何是如何实现的)

Spring中getBean的主体思路

BeanFactory实现getBean方法在AbstractBeanFactory中,这个方法重载都是调用doGetBean方法进行实现的:

1
2
3
4
5
6
7
8
9
10
11
12
13
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
public Object getBean(String name, Object... args) throws BeansException {
return doGetBean(name, null, args, false);
}
public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)
throws BeansException {
return doGetBean(name, requiredType, args, false);
}

doGetBean

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
// 版本:spring-beans-5.2.9-RELEASE
// AbstractBeanFactory#doGetBean
// 参数typeCheckOnly:bean实例是否包含一个类型检查
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

// 处理别名BeanName、处理带&符的工厂BeanName
// 解析bean的真正name,如果bean是工厂类,name前缀会加&,需要去掉
final String beanName = transformedBeanName(name);
Object bean;

// 从单例缓存中获取对象
Object sharedInstance = getSingleton(beanName);
// 一、单例缓存中有 && 为无参单例args == null
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
// 如果单例bean的实例正在创建中,则直接抛出异常
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 + "'");
}
}

// 1. 如果 sharedInstance 是普通的 Bean 实例,则下面的方法会直接返回
// 2. 如果 sharedInstance 是 FactoryBean 类型,则需要获取 getObject 方法,可以参考关于 FactoryBean 的实现类
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}

// 二、单例缓存中没有
else {
// 循环依赖有三种,setter注入、多实例和构造函数
// Spring 只能解决 setter 注入,所以这里是 Prototype 则会抛出异常
// 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.
BeanFactory parentBeanFactory = getParentBeanFactory();
// 【父 bean 工厂存在 && bean 不存在于当前bean工厂】,则委派给父Bean工厂获取
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
// 获取 name 对应的 beanName,如果 name 是以 & 开头,则返回 & + beanName
String nameToLookup = originalBeanName(name);

if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}

// typeCheckOnly,用于判断调用 getBean 方法时,是否仅是做类型检查
// 如果不是只做类型检查,就会调用 markBeanAsCreated 进行记录
if (!typeCheckOnly) {
// 将当前bean实例放入alreadyCreated集合里,标识这个bean准备创建了
markBeanAsCreated(beanName);
}

try {
// 这里通过beanName获取相关信息来组装RootBeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 检查当前创建的 bean 定义是否为抽象 bean 定义
checkMergedBeanDefinition(mbd, beanName, args);

// 当前Bean的依赖项
// 在实例化自己之前,需要先实例化自己依赖的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 监测是否存在 depends-on 循环依赖,若存在则会抛出异常
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 注册依赖记录
registerDependentBean(dep, beanName);
try {
// 加载 depends-on 依赖(dep 是 depends-on 缩写)
// 初始化当前bean依赖的bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}

// 此处开始创建实例对象
// 1、创建Bean实例:单例
if (mbd.isSingleton()) {
// 把 beanName 和 new ObjectFactory 匿名内部类传入回调
sharedInstance = getSingleton(beanName, () -> {
try {
// 真正创建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.
// 创建失败则销毁
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 2、创建Bean实例:原型
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 3、创建Bean实例:根据bean的scope创建
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
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) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}

// Check if required type matches the type of the actual bean instance.
// 如果需要类型转换,这里会进行操作
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
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());
}
}
return (T) bean;
}

这段代码很长,主体逻辑如下:

  • 解析bean的真正name,如果bean是工厂类,name前缀会加&,需要去掉
  • 先从单例缓存中尝试获取getSingleton(beanName)
    • 如果单例缓存中有 && args == null
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      // Eagerly check singleton cache for manually registered singletons.
      Object sharedInstance = getSingleton(beanName);
      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 + "'");
      }
      }
      bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
      }
      • 如果bean单例正在创建中,打印日志
      • bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    • 如果单例缓存中没有:
      • 如果bean实例正在创建中,则直接抛出异常
        1
        2
        3
        4
        5
        // Fail if we're already creating this bean instance:
        // We're assumably within a circular reference.
        if (isPrototypeCurrentlyInCreation(beanName)) {
        throw new BeanCurrentlyInCreationException(beanName);
        }
      • 如果bean definition 不存在于当前bean工厂中,则委派给父Bean工厂获取
      • 标记这个beanName的实例正在创建
      • 确保它的依赖也被初始化
      • 真正创建
        1. 单例时
        2. 原型时
        3. 根据bean的scope创建

二、Spring如何解决循环依赖问题

首先需要说明:

  1. Spring只是解决了单例模式setter注入的循环依赖问题;
  2. Spring为了解决单例的循环依赖问题,使用了三级缓存

Spring单例模式下的setter注入和三级缓存

先来看下这三级缓存

1
2
3
4
5
6
7
8
9
// public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry
/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);

/** Cache of early singleton objects: bean name --> bean instance */
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<String, Object>(16);

/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
  • 第一层缓存(singletonObjects):单例对象缓存池,已经实例化并且属性赋值,这里的对象是成熟对象
  • 第二层缓存(earlySingletonObjects):单例对象缓存池,已经实例化但尚未属性赋值,这里的对象是半成品对象
  • 第三层缓存(singletonFactories): 单例工厂的缓存
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
// DefaultSingletonBeanRegistry#getSingleton
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Quick check for existing instance without full singleton lock
// 1. Spring首先从singletonObjects(一级缓存)中尝试获取
Object singletonObject = this.singletonObjects.get(beanName);
// 2. 若是获取不到 && 对象在建立中,则尝试从earlySingletonObjects(二级缓存)中获取
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName);
// 3. 若是二级缓存获取不到 && 【allowEarlyReference=true 允许从singletonFactories经过getObject获取】
// 则经过singletonFactory.getObject()(三级缓存)获取
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) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
// 经过singletonFactory.getObject()(三级缓存)获取到了
// 则将singletonObject放入到earlySingletonObjects,也就是将三级缓存提高到二级缓存中
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
  • allowEarlyReference
    是否容许从singletonFactories中经过getObject拿到对象
  • isSingletonCurrentlyInCreation()
    判断当前单例bean是否正在建立中,也就是没有初始化完成。
    (好比A的构造器依赖了B对象因此得先去建立B对象, 或则在A的populateBean过程当中依赖了B对象,得先去建立B对象,这时的A就是处于建立中的状态。)

分析getSingleton()的整个过程,Spring首先从一级缓存singletonObjects中获取。若是获取不到,而且对象正在建立中,就再从二级缓存earlySingletonObjects中获取。若是仍是获取不到且容许singletonFactories经过getObject()获取,就从**三级缓存singletonFactory.getObject()(三级缓存)**获取,若是获取到了则将其put进二级缓存。

从上面三级缓存的分析,咱们能够知道,Spring解决循环依赖的诀窍就在于singletonFactories这个三级cache
这个cache的类型是ObjectFactory,定义以下:

1
2
3
public interface ObjectFactory<T> {
T getObject() throws BeansException;
}

在bean建立过程当中,有两处比较重要的匿名内部类实现了ObjectFactory接口。

  1. 一处是Spring利用其建立bean的时候
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // AbstractBeanFactory#doGetBean
    // 1、创建Bean实例:单例
    if (mbd.isSingleton()) {
    // 此处lambda表达式为ObjectFactory的实现
    sharedInstance = getSingleton(beanName, () -> {
    try {
    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.
    destroySingleton(beanName);
    throw ex;
    }
    });
    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    }
  2. 另外一处就是:AbstractAutowireCapableBeanFactory#doCreateBean#addSingletonFactory

doCreateBean bean的创建

  • 在 doCreateBean 方法中包括的内容较多,但核心主要是创建实例、加入缓存以及最终进行属性填充,属性填充就是把一个bean的各个属性字段涉及到的类填充进去。
  • createBeanInstance,创建 bean 实例,并将 bean 实例包装到 BeanWrapper 对象中返回
  • addSingletonFactory,添加 bean 工厂对象到 singletonFactories 缓存中
  • getEarlyBeanReference,获取原始对象的早期引用,在 getEarlyBeanReference 方法中,会执行 AOP 相关逻辑。若 bean 未被 AOP 拦截,getEarlyBeanReference 原样返回 bean。
  • populateBean,填充属性,解析依赖关系。也就是从这开始去找寻 A 实例中属性 B,紧接着去创建 B 实例,最后在返回回来。
  • initializeBean(beanName, exposedObject, mbd):完成 bean 的属性填充注入后,进一步初始化 bean,在此过程中产生代理对象。此时 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
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
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}});

// AbstractAutowireCapableBeanFactory#doCreateBean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// 实例化bean
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 先尝试从缓存中取
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 调用构造方法创建一个空实例对象,并用BeanWrapper进行包装
// 通过构造方法反射得到一个空实例对象
// 由此可知无法解决构造方法注入的循环依赖
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}

// 允许后置处理程序修改合并后的bean定义
// Allow post-processors to modify the merged bean definition.
// 获取所有的后置处理器,如果后置处理器实现了MergedBeanDefinitionPostProcessor接口,则一次调用其postProcessMergedBeanDefinition方法
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}

// allowCircularReferences 自动尝试解析bean之间的循环引用
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 如果满足循环依赖缓存条件,先缓存具体对象
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}

// 此处是解决循环依赖的关键!!!
// 循环依赖处理逻辑:将已完成实例化,但是未完成属性赋值和相关的初始化的一个不完整的bean添加到三级缓存singletonFactories中
// 具体内部会遍历后置处理器,判断是否有SmartInstantiationAwareBeanPostProcessor的实现类,然后调用里面getEarlyBeanReference覆盖当前Bean
// 默认不做任何操作返回当前Bean,作为拓展,这里比如可以供AOP来创建代理类
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

// 开始对Bean实例进行初始化
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 对bean进行属性填充,在这里面完成依赖注入的相关内容
populateBean(beanName, mbd, instanceWrapper);
// 完成属性依赖注入后,进一步初始化Bean
// 具体进行了以下操作:
// 1.若实现了BeanNameAware,BeanClassLoaderAware,BeanFactoryAwareAware等接口,则注入相关对象
// 2.遍历后置处理器,调用实现的postProcessBeforeInitialization方法,
// 3.如果实现了initialzingBean,调用实现的 afterPropertiesSet()
// 4.如果配置了init-mothod,调用相应的init方法
// 5.遍历后置处理器,调用实现的postProcessAfterInitialization
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}

... // 后续代码省略
}

Spring为何不能解决非单例属性之外的循环依赖?

Spring是借助单例的三级缓存来解决单例的setter注入的循环依赖。

Spring为什么不能解决构造器的循环依赖?

构造器注入形成的循环依赖: 也就是beanB需要在beanA的构造函数中完成初始化,beanA也需要在beanB的构造函数中完成初始化,这种情况的结果就是两个bean都不能完成初始化,循环依赖难以解决。
Spring解决循环依赖主要是依赖三级缓存,但是在调用构造方法之前还未将其放入三级缓存之中,因此后续的依赖调用构造方法的时候并不能从三级缓存中获取到依赖的Bean,因此不能解决。

Spring为什么不能解决prototype作用域循环依赖?

这种循环依赖同样无法解决,因为spring不会缓存‘prototype’作用域的bean,而spring中循环依赖的解决正是通过缓存来实现的。

Spring为什么不能解决多例的循环依赖?

多实例Bean是每次调用一次getBean都会执行一次构造方法并且给属性赋值,根本没有三级缓存,因此不能解决循环依赖。

其它循环依赖如何解决?

  • 生成代理对象产生的循环依赖
    1. 使用@Lazy注解,延迟加载
    2. 使用@DependsOn注解,指定加载先后关系
    3. 修改文件名称,改变循环依赖类的加载顺序
  • 使用@DependsOn产生的循环依赖
    这类循环依赖问题要找到@DependsOn注解循环依赖的地方,迫使它不循环依赖就可以解决问题。
  • 多例循环依赖
    这类循环依赖问题可以通过把bean改成单例的解决。
  • 构造器循环依赖
    这类循环依赖问题可以通过使用@Lazy注解解决。

三、Spring中Bean的生命周期

Spring 只帮我们管理单例模式 Bean 的完整生命周期;对于 prototype 的 bean ,Spring 在创建好交给使用者之后则不会再管理后续的生命周期。

Spring 容器可以管理 singleton 作用域 Bean 的生命周期,在此作用域下,Spring 能够精确地知道该 Bean 何时被创建,何时初始化完成,以及何时被销毁。

而对于 prototype 作用域的 Bean,Spring 只负责创建,当容器创建了 Bean 的实例后,Bean 的实例就交给客户端代码管理,Spring 容器将不再跟踪其生命周期。每次客户端请求 prototype 作用域的 Bean 时,Spring 容器都会创建一个新的实例,并且不会管那些被配置成 prototype 作用域的 Bean 的生命周期。

了解 Spring 生命周期的意义就在于,可以利用 Bean 在其存活期间的指定时刻完成一些相关操作。这种时刻可能有很多,但一般情况下,会在 Bean 被初始化后和被销毁前执行一些相关操作。

Spring 容器中 Bean 的生命周期流程