前言:在【spring源码分析】IOC容器初始化(六)中分析了从单例缓存中加载bean对象,由于篇幅原因其核心函数
FactoryBeanRegistrySupport#getObjectFromFactoryBean并未进行详细分析,本文将继续对bean加载过程的分析。
FactoryBeanRegistrySupport#getObjectFromFactoryBean
1 protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
2 // 为单例模式,其缓存中存在该bean实例
3 if (factory.isSingleton() && containsSingleton(beanName)) {
4 /**
5 * 做同步,内部其实使用的就是{@link DefaultSingletonBeanRegistry#singletonObjects}
6 */
7 synchronized (getSingletonMutex()) {
8 // 从缓存中获取指定的factoryBean
9 Object object = this.factoryBeanObjectCache.get(beanName);
10 if (object == null) {
11 // 为空,则从FactoryBean中获取对象
12 object = doGetObjectFromFactoryBean(factory, beanName);
13 // Only post-process and store if not put there already during getObject() call above
14 // (e.g. because of circular reference processing triggered by custom getBean calls)
15 // 再次从缓存中获取bean对象,主要是因为循环依赖
16 Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
17 if (alreadyThere != null) {
18 object = alreadyThere;
19 } else {
20 // 需要后续处理
21 if (shouldPostProcess) {
22 // 如果该Bean处于创建中,则返回处理对象,而不是存储该对象
23 if (isSingletonCurrentlyInCreation(beanName)) {
24 // Temporarily return non-post-processed object, not storing it yet..
25 return object;
26 }
27 // 单例bean的前置处理 用于添加标志,当前bean正处于创建中
28 beforeSingletonCreation(beanName);
29 try {
30 // 对FactoryBean获取的对象进行后置处理,返回生成的对象
31 object = postProcessObjectFromFactoryBean(object, beanName);
32 } catch (Throwable ex) {
33 throw new BeanCreationException(beanName,
34 "Post-processing of FactoryBean's singleton object failed", ex);
35 } finally {
36 // 单例bean的后置处理 和前置处理相反,前置添加,后置移除 移除标志,当前bean不处于创建中
37 afterSingletonCreation(beanName);
38 }
39 }
40 // 添加到factoryBeanObjectCache中进行缓存
41 if (containsSingleton(beanName)) {
42 this.factoryBeanObjectCache.put(beanName, object);
43 }
44 }
45 }
46 return object;
47 }
48 } else {
49 // 不满足第一个条件,不是单例,或者缓存中不存在,则从FactoryBean中获取对象
50 Object object = doGetObjectFromFactoryBean(factory, beanName);
51 // 需要后续处理
52 if (shouldPostProcess) {
53 try {
54 // 对FactoryBean获取的对象进行后处理
55 // 返回生成的对象
56 object = postProcessObjectFromFactoryBean(object, beanName);
57 } catch (Throwable ex) {
58 throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
59 }
60 }
61 return object;
62 }
63 }
分析:
函数分两大分支:
#1.单例且singletonObjects缓存中存在(该分支为同步方法)
- #1.1:FactoryBean为单例,并且缓存中存在该bean对象(containsSingleton方法其实就是判断singletonObjects集合中是否存在bean对象),首先从缓存中获取factoryBean对象object,如果object=null,则从doGetObjectFromFactoryBean方法中获取对象。注意:这里再次从factoryBeanObjectCache缓存中尝试获取对象(主要是循环依赖问题,有可能这时该bean对象已经加载了,就不用再次加载了),如果缓存中已存在bean对象,则使用缓存中对象,并直接返回。
- #1.2:如果factoryBeanObjectCache缓存中不存在对象且需要后置处理,则首先判断该bean对象是否正在被创建,如果是,则直接返回,注意这里未进行缓存;然后对单例bean进行前置添加处理(beforeSingletonCreation)、后置处理(postProcessObjectFromFactoryBean)、后置移除标志处理(afterSingletonCreation)。
- #1.3:最后将缓存生成的bean对象
#2.不满足(#1)中的任何一条件
- 首先从doGetObjectFromFactoryBean方法中获取获取bean对象,如果需要后置处理,则调用postProcessObjectFromFactoryBean方法进行处理,最后返回生成过的bean对象。
在上述分析中涉及到几个函数,下面一一进行分析。
FactoryBeanRegistrySupport#doGetObjectFromFactoryBean
1 private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
2 throws BeanCreationException {
3
4 Object object;
5 try {
6 // 如果权限不为空
7 if (System.getSecurityManager() != null) {
8 AccessControlContext acc = getAccessControlContext();
9 try {
10 // 从FactoryBean中获取Bean对象[factory::getObject] 其实与else分支一样的
11 object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
12 } catch (PrivilegedActionException pae) {
13 throw pae.getException();
14 }
15 } else {
16 // 如果权限为空,则从Factory中获取Bean对象
17 object = factory.getObject();
18 }
19 } catch (FactoryBeanNotInitializedException ex) {
20 throw new BeanCurrentlyInCreationException(beanName, ex.toString());
21 } catch (Throwable ex) {
22 throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
23 }
24
25 // 进行一波校验
26 // Do not accept a null value for a FactoryBean that's not fully
27 // initialized yet: Many FactoryBeans just return null then.
28 if (object == null) {
29 // 如果bean正在被创建,则抛出异常
30 if (isSingletonCurrentlyInCreation(beanName)) {
31 throw new BeanCurrentlyInCreationException(
32 beanName, "FactoryBean which is currently in creation returned null from getObject");
33 }
34 object = new NullBean();
35 }
36 return object;
37 }
根据是否具有权限,通过FactoryBean#getObject获取bean对象,如果bean对象为null且正在被创建,则抛出异常,否则实例化一个NullBean对象进行返回。
DefaultSingletonBeanRegistry#isSingletonCurrentlyInCreation
1 /**
2 * 正在创建中的单例 Bean 的名字的集合
3 * Names of beans that are currently in creation.
4 */
5 private final Set<String> singletonsCurrentlyInCreation =
6 Collections.newSetFromMap(new ConcurrentHashMap<>(16));
7
8 public boolean isSingletonCurrentlyInCreation(String beanName) {
9 return this.singletonsCurrentlyInCreation.contains(beanName);
10 }
该函数判断bean是否正处于创建之中,该方法要与beforeSingletonCreation和afterSingletonCreation配合起来分析才能明白其重要性,他们记录了bean的加载状态,是检查当前bean是否处于创建中的关键处,对解决bean的循环依赖起着重要作用。
DefaultSingletonBeanRegistry#beforeSingletonCreation
1 protected void beforeSingletonCreation(String beanName) {
2 // 这里会添加到正在创建bean的集合中
3 // 注意第一个条件,如果存在,则为false,直接短路
4 // 只有当第一个条件不存在[false]时,才会去进行添加操作
5 if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
6 throw new BeanCurrentlyInCreationException(beanName);
7 }
8 }
注意这里就会将正在创建的beanName添加到singletonsCurrentlyInCreation集合中,第一个条件是判断该bean是否不会被检测。
DefaultSingletonBeanRegistry#afterSingletonCreation
1 protected void afterSingletonCreation(String beanName) {
2 if (!this.inCreationCheckExclusions.contains(beanName)
3 && !this.singletonsCurrentlyInCreation.remove(beanName)) { // 移除
4 // 如果移除失败,则抛出IllegalStateException异常
5 throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
6 }
7 }
afterSingletonCreation方法与beforeSingletonCreation方法的功能相反,用于将beanName移除正在创建的集合singletonsCurrentlyInCreation,表明bean创建完成。
postProcessObjectFromFactoryBean
该方法的默认实现,就是返回当前bean对象。
1 // FactoryBeanRegistrySupport
2 protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException {
3 return object;
4 }
当然,子类可以对该方法进行重写。
1 // AbstractAutowireCapableBeanFactory
2
3 protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
4 return applyBeanPostProcessorsAfterInitialization(object, beanName);
5 }
6
7 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
8 throws BeansException {
9
10 Object result = existingBean;
11 // 遍历BeanPostProcessor
12 for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
13 // 进行处理
14 // TODO: 2019/4/2 具体处理过程需详细查看,这里先走大流程
15 Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
16 // 返回为空,则返回传入的Object对象
17 if (current == null) {
18 return result;
19 }
20 // 修改result
21 result = current;
22 }
23 return result;
24 }
这里主要是遍历BeanPostProcessor,然后对bean对象进行处理,关于后置处理器的分析后面再做分析。
到这里从单例缓存中获取bean对象的相应源码已分析完成,接下来看单例缓存中无bean对象时,Spring的处理流程,再次将getBean的切入点代码贴出来。
1 protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
2 @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
3
4 // .........省略从单例缓存中获取bean对象的代码
5 } else {
6 // Fail if we're already creating this bean instance:
7 // We're assumably within a circular reference.
8 // Spring只能解决单例模式下的循环依赖,在原型模式下如果存在循环依赖则抛出异常
9 // 这里检测原型模式下,该bean是否在加载,如果在加载则抛出异常
10 if (isPrototypeCurrentlyInCreation(beanName)) {
11 throw new BeanCurrentlyInCreationException(beanName);
12 }
13
14 // 如果当前容器中没有找到,则从父类容器中加载
15 // Check if bean definition exists in this factory.
16 BeanFactory parentBeanFactory = getParentBeanFactory();
17 /**
18 * 调用{@link DefaultListableBeanFactory#containsBeanDefinition(String)}方法
19 * 其实就是在beanDefinitionMap中判断是否存在beanName对应的BeanDefinition
20 */
21 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
22 // Not found -> check parent.
23 // 确定原始的beanName
24 String nameToLookup = originalBeanName(name);
25 // 如果父类容器为AbstractBeanFactory,则委托父类处理
26 if (parentBeanFactory instanceof AbstractBeanFactory) {
27 return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
28 nameToLookup, requiredType, args, typeCheckOnly);
29 } else if (args != null) { // 用明确的args从parentBeanFactory中,获取Bean对象
30 // Delegation to parent with explicit args.
31 // 委托给父类构造函数getBean()处理
32 return (T) parentBeanFactory.getBean(nameToLookup, args);
33 } else if (requiredType != null) { // 用明确的requiredType从parentBeanFactory中,获取Bean对象
34 // No args -> delegate to standard getBean method.
35 // 没有args,委托给标准的getBean()处理
36 return parentBeanFactory.getBean(nameToLookup, requiredType);
37 } else {
38 // 直接使用nameToLookup从parentBeanFactory中获取Bean对象
39 return (T) parentBeanFactory.getBean(nameToLookup);
40 }
41 }
42
43 // 如果不仅仅是做类型检查,而是创建bean,这里需要记录
44 if (!typeCheckOnly) {
45 markBeanAsCreated(beanName);
46 }
47
48 try {
49 /**
50 * 从容器中获取beanName对应的GenericBeanDefinition对象,并转换成RootBeanDefinition对象
51 * GenericBeanDefinition的创建{@link BeanDefinitionReaderUtils#createBeanDefinition}方法
52 */
53 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
54 // 检查合并的BeanDefinition
55 checkMergedBeanDefinition(mbd, beanName, args);
56
57 // Guarantee initialization of beans that the current bean depends on.
58 // 处理所依赖的bean
59 String[] dependsOn = mbd.getDependsOn();
60 if (dependsOn != null) {
61 for (String dep : dependsOn) {
62 // 若给定的依赖bean已经注册为依赖给定的bean
63 // 即循环依赖情况,抛出BeanCreationException异常
64 if (isDependent(beanName, dep)) {
65 throw new BeanCreationException(mbd.getResourceDescription(), beanName,
66 "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
67 }
68 // 缓存依赖调用
69 registerDependentBean(dep, beanName);
70 try {
71 // 递归处理依赖 Bean
72 getBean(dep);
73 } catch (NoSuchBeanDefinitionException ex) {
74 throw new BeanCreationException(mbd.getResourceDescription(), beanName,
75 "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
76 }
77 }
78 }
79 // bean实例化
80 // Create bean instance.
81 // 单例模式
82 /**
83 * 这里有个已创建bean的重要方法createBean
84 * {@link AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[])}
85 */
86 if (mbd.isSingleton()) {
87 sharedInstance = getSingleton(beanName, () -> {
88 try {
89 return createBean(beanName, mbd, args);
90 } catch (BeansException ex) {
91 // Explicitly remove instance from singleton cache: It might have been put there
92 // eagerly by the creation process, to allow for circular reference resolution.
93 // Also remove any beans that received a temporary reference to the bean.
94 // 显式从单例缓存中删除Bean实例
95 // 因为单例模式下为了解决循环依赖,可能它已经存在,所以销毁它
96 destroySingleton(beanName);
97 throw ex;
98 }
99 });
100 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
101 } else if (mbd.isPrototype()) { // 原型模式
102 // It's a prototype -> create a new instance.
103 Object prototypeInstance = null;
104 try {
105 // 前置处理
106 beforePrototypeCreation(beanName);
107 /**
108 * 创建bean {@link AbstractAutowireCapableBeanFactory#createBean}
109 */
110 prototypeInstance = createBean(beanName, mbd, args);
111 } finally {
112 /**
113 * 后置处理 与前置处理相反从{@link prototypesCurrentlyInCreation}中移除
114 */
115 afterPrototypeCreation(beanName);
116 }
117 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
118 } else { //其他作用域
119 // 获得scopeName对应的Scope对象
120 String scopeName = mbd.getScope();
121 final Scope scope = this.scopes.get(scopeName);
122 if (scope == null) {
123 throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
124 }
125 try {
126 /**
127 * 从指定的scope下创建bean
128 * {@link SimpleThreadScope#get方法}
129 */
130 Object scopedInstance = scope.get(beanName, () -> {
131 beforePrototypeCreation(beanName);
132 try {
133 return createBean(beanName, mbd, args);
134 } finally {
135 afterPrototypeCreation(beanName);
136 }
137 });
138 bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
139 } catch (IllegalStateException ex) {
140 throw new BeanCreationException(beanName,
141 "Scope '" + scopeName + "' is not active for the current thread; consider " +
142 "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
143 ex);
144 }
145 }
146 } catch (BeansException ex) {
147 cleanupAfterBeanCreationFailure(beanName);
148 throw ex;
149 }
150 }
151
152 // 检查需要的类型是否符合bean的实际类型
153 // Check if required type matches the type of the actual bean instance.
154 if (requiredType != null && !requiredType.isInstance(bean)) {
155 try {
156 T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
157 if (convertedBean == null) {
158 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
159 }
160 return convertedBean;
161 } catch (TypeMismatchException ex) {
162 if (logger.isTraceEnabled()) {
163 logger.trace("Failed to convert bean '" + name + "' to required type '" +
164 ClassUtils.getQualifiedName(requiredType) + "'", ex);
165 }
166 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
167 }
168 }
169 return (T) bean;
170 }
#1.首先通过AbstractBeanFactory#isPrototypeCurrentlyInCreation检查bean对象是否处于原型模式下的循环依赖,因为Spring只能解决单例模式下的循环依赖,如果在原型模式下也存在该bean对象,则会抛出异常。
1 // AbstractBeanFactory
2 /**
3 * 原型模式下存储beanName的ThreadLocal<br/>
4 * Names of beans that are currently in creation.
5 */
6 private final ThreadLocal<Object> prototypesCurrentlyInCreation =
7 new NamedThreadLocal<>("Prototype beans currently in creation");
8 protected boolean isPrototypeCurrentlyInCreation(String beanName) {
9 Object curVal = this.prototypesCurrentlyInCreation.get();
10 return (curVal != null &&
11 (curVal.equals(beanName) //相等
12 || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName)))); // 包含
13 }
- 这里就是检查原型模式的ThreadLocal中是否已经存在对应的beanName。
#2.AbstractBeanFactory#getParentBeanFactory检查其父类BeanFactory是否存在,如果存在且beanDefinitionMap中不存在该BeanDefinition,则委托其父类通过getBean方法获取bean对象。注意这里首先会通过originalBeanName方法获取原始beanName。
1 // AbstractBeanFactory
2 protected String originalBeanName(String name) {
3 String beanName = transformedBeanName(name);
4 if (name.startsWith(FACTORY_BEAN_PREFIX)) {
5 // 如果beanName以&开头,则在加上&进行返回 因为transformedBeanName中会去掉&
6 beanName = FACTORY_BEAN_PREFIX + beanName;
7 }
8 return beanName;
9 }
- 首先通过transformedBeanName(该方法前面已经分析)获取真正的beanName,如果name以"&"开头,则将beanName加上"&"符号,因为transformedBeanName方法会去掉"&"符号。
#3.判断bean是否需要做类型检查,如果不仅仅做类型检查,则需要调用markBeanAsCreated函数进行记录。
1 // AbstractBeanFactory
2 /**
3 * 已创建Bean的名字集合<br/>
4 * Names of beans that have already been created at least once.
5 */
6 private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
7
8
9 protected void markBeanAsCreated(String beanName) {
10 // 没有创建
11 if (!this.alreadyCreated.contains(beanName)) {
12 // 做同步
13 synchronized (this.mergedBeanDefinitions) {
14 // 再次进行检查,DoubleCheck模式
15 if (!this.alreadyCreated.contains(beanName)) {
16 // Let the bean definition get re-merged now that we're actually creating
17 // the bean... just in case some of its metadata changed in the meantime.
18 // 从mergedBeanDefinitions中删除beanName,并在下次访问时重新创建它
19 clearMergedBeanDefinition(beanName);
20 // 添加到已创建bean集合中
21 this.alreadyCreated.add(beanName);
22 }
23 }
24 }
25 }
#4. 接下来将对BeanDefinition进行转换,因为最开始创建的BeanDefinition类型为GenericBeanDefinition,getMergedLocalBeanDefinition方法在前面已经进行了分析,这里不在赘述。
#5.调用checkMergedBeanDefinition对转换后的RootBeanDefinition,如果RootBeanDefinition仍为抽象的,则抛出异常,这里抽象的对象还不能进行实例化。代码如下:
1 // AbstractBeanFactory
2 protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, @Nullable Object[] args)
3 throws BeanDefinitionStoreException {
4
5 if (mbd.isAbstract()) {
6 throw new BeanIsAbstractException(beanName);
7 }
8 }
#6.处理依赖,如果在加载bean对象时,发现它有依赖bean的话,那么在初始化该bean的时候需要先初始化依赖的bean对象
1 // 处理所依赖的bean
2 String[] dependsOn = mbd.getDependsOn();
3 if (dependsOn != null) {
4 for (String dep : dependsOn) {
5 // 若给定的依赖bean已经注册为依赖给定的bean
6 // 即循环依赖情况,抛出BeanCreationException异常
7 if (isDependent(beanName, dep)) {
8 throw new BeanCreationException(mbd.getResourceDescription(), beanName,
9 "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
10 }
11 // 缓存依赖调用
12 registerDependentBean(dep, beanName);
13 try {
14 // 递归处理依赖 Bean
15 getBean(dep);
16 } catch (NoSuchBeanDefinitionException ex) {
17 throw new BeanCreationException(mbd.getResourceDescription(), beanName,
18 "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
19 }
20 }
21 }
DefaultSingletonBeanRegistry#isDependent
1 protected boolean isDependent(String beanName, String dependentBeanName) {
2 synchronized (this.dependentBeanMap) {
3 return isDependent(beanName, dependentBeanName, null);
4 }
5 }
6 private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
7 // alreadySeen 已经检测的依赖bean
8 if (alreadySeen != null && alreadySeen.contains(beanName)) {
9 return false;
10 }
11 // 获取原始的beanName
12 String canonicalName = canonicalName(beanName);
13 // 获取当前beanName的依赖集合
14 Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
15 // 不存在,则说明不存在注册依赖
16 if (dependentBeans == null) {
17 return false;
18 }
19 // 存在,则证明已经存在注册依赖
20 if (dependentBeans.contains(dependentBeanName)) {
21 return true;
22 }
23 // 递归检测依赖
24 for (String transitiveDependency : dependentBeans) {
25 if (alreadySeen == null) {
26 alreadySeen = new HashSet<>();
27 }
28 // 添加到alreadySeen
29 alreadySeen.add(beanName);
30 // 递推
31 if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
32 return true;
33 }
34 }
35 return false;
36 }
这里通过一些列判断,是否依赖的bean是否已经注入,如果注入则返回true,否则返回false。
#7.如果依赖检测通过,则调用registerDependentBean对依赖bean进行注入。
1 // DefaultSingletonBeanRegistry
2
3 /**
4 * 保存的是依赖beanName 映射关系:beanName --> 依赖beanName的集合<br/>
5 * Map between dependent bean names: bean name to Set of dependent bean names.
6 */
7 private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
8
9 /**
10 * 保存的是依赖 beanName 之间的映射关系:依赖 beanName - > beanName 的集合
11 * Map between depending bean names: bean name to Set of bean names for the bean's dependencies.
12 */
13 private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
14
15 public void registerDependentBean(String beanName, String dependentBeanName) {
16 // 获取beanName
17 String canonicalName = canonicalName(beanName);
18
19 // 做同步 添加<canonicalName,<dependentBeanName>>到dependentBeanMap中
20 synchronized (this.dependentBeanMap) {
21 Set<String> dependentBeans =
22 this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
23 if (!dependentBeans.add(dependentBeanName)) {
24 return;
25 }
26 }
27 // 做同步 添加<canonicalName,<dependentBeanName>>到dependenciesForBeanMap中
28 synchronized (this.dependenciesForBeanMap) {
29 Set<String> dependenciesForBean =
30 this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
31 dependenciesForBean.add(canonicalName);
32 }
33 }
这里就是就是将依赖的beanName关系添加到dependentBeanMap、dependenciesForBeanMap集合中。
#8.最后通过getBean方法实例化依赖bean对象,该方法会在后面进行分析。
各种scope的Bean创建
在经过单例缓存中获取bean对象、从父类工厂中获取bean对象、处理依赖bean这三步后,接下来来到对各种scope的bean的创建。首先是单例模式bean对象的创建,我们知道singleton为Spring的bean的默认作用域,当然除了singleton之外,还有prototype、request等其他的scope。
#1.singleton的初始化代码如下
1 // AbstractBeanFactory
2
3 if (mbd.isSingleton()) {
4 sharedInstance = getSingleton(beanName, () -> {
5 try {
6 return createBean(beanName, mbd, args);
7 } catch (BeansException ex) {
8 // Explicitly remove instance from singleton cache: It might have been put there
9 // eagerly by the creation process, to allow for circular reference resolution.
10 // Also remove any beans that received a temporary reference to the bean.
11 // 显式从单例缓存中删除Bean实例
12 // 因为单例模式下为了解决循环依赖,可能它已经存在,所以销毁它
13 destroySingleton(beanName);
14 throw ex;
15 }
16 });
17 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
18 }
单例模式bean的初始化是从getSingleton方法开始,当然这里还有一个重要的createBean方法,该方法我们留在后面进行分析,首先来看getSingleton方法。
1 // DefaultSingletonBeanRegistry
2
3 public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
4 Assert.notNull(beanName, "Bean name must not be null");
5 // 做同步
6 synchronized (this.singletonObjects) {
7 // 从缓存中检查一遍
8 // 因为singlton模式其实已经复用了创建的bean,所以该步骤必须检查
9 Object singletonObject = this.singletonObjects.get(beanName);
10 // 为空,开始进行加载
11 if (singletonObject == null) {
12 if (this.singletonsCurrentlyInDestruction) {
13 throw new BeanCreationNotAllowedException(beanName,
14 "Singleton bean creation not allowed while singletons of this factory are in destruction " +
15 "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
16 }
17 if (logger.isDebugEnabled()) {
18 logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
19 }
20 // 加载前置处理 其实就是打一个标记
21 beforeSingletonCreation(beanName);
22 // 首先将新的newSingleton设置为false
23 boolean newSingleton = false;
24 boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
25 if (recordSuppressedExceptions) {
26 this.suppressedExceptions = new LinkedHashSet<>();
27 }
28 try {
29 // 初始化bean
30 // 该过程其实是调用createBean()方法 这里是一个回调方法
31 singletonObject = singletonFactory.getObject();
32 newSingleton = true;
33 } catch (IllegalStateException ex) {
34 // Has the singleton object implicitly appeared in the meantime ->
35 // if yes, proceed with it since the exception indicates that state.
36 singletonObject = this.singletonObjects.get(beanName);
37 if (singletonObject == null) {
38 throw ex;
39 }
40 } catch (BeanCreationException ex) {
41 if (recordSuppressedExceptions) {
42 for (Exception suppressedException : this.suppressedExceptions) {
43 ex.addRelatedCause(suppressedException);
44 }
45 }
46 throw ex;
47 } finally {
48 if (recordSuppressedExceptions) {
49 this.suppressedExceptions = null;
50 }
51 // 一堆异常处理后,进行后置处理 移除标志
52 afterSingletonCreation(beanName);
53 }
54 // 新的bean 加入缓存中
55 if (newSingleton) {
56 addSingleton(beanName, singletonObject);
57 }
58 }
59 return singletonObject;
60 }
61 }
分析(该方法同样为同步方法):
该方法其实并未真正创建bean对象,获取bean对象的核心点在于singletonObject = singletonFactory.getObject(),但该方法是由createBean回调产生的。这里仅仅是做了一部分准备和预处理步骤:
- 再次从缓存中检查bean是否已经加载过,如果缓存中存在则直接返回。
- beforeSingletonCreation前面已经分析过,记录加载单例bean的状态,表示正在被加载。
- 然后调用singletonFactory.getObject方法实例化bean对象
- afterSingletonCreation前面也分析过了,移除bean正在被加载的标志。
- 将生成的bean对象加入缓存。
DefaultSingletonBeanRegistry#addSingleton
1 /**
2 * Cache of singleton objects: bean name to bean instance.
3 * 存放的是单例 bean 的映射。
4 * <p>
5 * 对应关系为 bean name --> bean instance
6 */
7 private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
8
9 /**
10 * Cache of singleton factories: bean name to ObjectFactory.<br/>
11 * 存放的是 ObjectFactory,可以理解为创建单例 bean 的 factory 。
12 * <p>
13 * 对应关系是 bean name --> ObjectFactory
14 */
15 private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
16
17 /**
18 * Cache of early singleton objects: bean name to bean instance.<br/>
19 * 存放的是早期的 bean,对应关系也是 bean name --> bean instance。
20 * <p>
21 * 它与 {@link #singletonFactories} 区别在于 earlySingletonObjects 中存放的 bean 不一定是完整。
22 * <p>
23 * 从 {@link #getSingleton(String)} 方法中,我们可以了解,bean 在创建过程中就已经加入到 earlySingletonObjects 中了。
24 * 所以当在 bean 的创建过程中,就可以通过 getBean() 方法获取。
25 * <p>
26 * 这个 Map 也是【循环依赖】的关键所在。
27 */
28 private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
29
30 /**
31 * 存储已经注册的单例 进行缓存<br/>
32 * Set of registered singletons, containing the bean names in registration order.
33 */
34 private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
35
36 protected void addSingleton(String beanName, Object singletonObject) {
37 synchronized (this.singletonObjects) {
38 this.singletonObjects.put(beanName, singletonObject);
39 this.singletonFactories.remove(beanName);
40 this.earlySingletonObjects.remove(beanName);
41 this.registeredSingletons.add(beanName);
42 }
43 }
一个put、两个remove、一个add。
- 由于已经实例化了bean,因此需要将单例bean进行缓存,singletonObjects.put。
- 同理单例BeanFactory和提前曝光的bean也需要移除,singletonFactories.remove和earlySingletonObjects.remove。
- registeredSingletons.add,已实例化的bean需要进行注册。
#2.原型模式
1 if (mbd.isPrototype()) { // 原型模式
2 // It's a prototype -> create a new instance.
3 Object prototypeInstance = null;
4 try {
5 // 前置处理
6 beforePrototypeCreation(beanName);
7 /**
8 * 创建bean {@link AbstractAutowireCapableBeanFactory#createBean}
9 */
10 prototypeInstance = createBean(beanName, mbd, args);
11 } finally {
12 /**
13 * 后置处理 与前置处理相反从{@link prototypesCurrentlyInCreation}中移除
14 */
15 afterPrototypeCreation(beanName);
16 }
17 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
18 }
原型模式下bean的初始化很简单,直接创建一个新Bean实例就可以了。
- beforePrototypeCreation:记录加载原型模式bean的加载状态,前置处理。
- createBean创建实例对象,该方法非常重要,后续会详细进行分析。
- afterPrototypeCreation:移除创建时添加的标志,后置处理与beforePrototypeCreation方法功能相反。
- 最后调用getObjectForBeanInstance获取实例,该方法在【spring源码分析】IOC容器初始化(六)中已经分析,这里不再赘述。
AbstractBeanFactory#beforePrototypeCreation
1 /**
2 * 原型模式下存储beanName的ThreadLocal<br/>
3 * Names of beans that are currently in creation.
4 */
5 private final ThreadLocal<Object> prototypesCurrentlyInCreation =
6 new NamedThreadLocal<>("Prototype beans currently in creation");
7
8 protected void beforePrototypeCreation(String beanName) {
9 // 从ThreadLocal中取出对象
10 Object curVal = this.prototypesCurrentlyInCreation.get();
11 if (curVal == null) {
12 // 如果为空,则设置值
13 this.prototypesCurrentlyInCreation.set(beanName);
14 } else if (curVal instanceof String) {
15 // 如果curVal为String类型,则进行添加
16 Set<String> beanNameSet = new HashSet<>(2);
17 beanNameSet.add((String) curVal);
18 beanNameSet.add(beanName);
19 this.prototypesCurrentlyInCreation.set(beanNameSet);
20 } else {
21 // 否则将curVal转换成set集合,添加beanName
22 Set<String> beanNameSet = (Set<String>) curVal;
23 beanNameSet.add(beanName);
24 }
25 }
这里的前置处理就是将beanName加入ThreadLocal中,逻辑简单。
AbstractBeanFactory#afterPrototypeCreation
1 protected void afterPrototypeCreation(String beanName) {
2 Object curVal = this.prototypesCurrentlyInCreation.get();
3 if (curVal instanceof String) {
4 this.prototypesCurrentlyInCreation.remove();
5 } else if (curVal instanceof Set) {
6 Set<String> beanNameSet = (Set<String>) curVal;
7 beanNameSet.remove(beanName);
8 if (beanNameSet.isEmpty()) {
9 this.prototypesCurrentlyInCreation.remove();
10 }
11 }
12 }
后置处理与前置处理beforePrototypeCreation正好相反,将标记从ThreadLocal中移除。
#3.其他作用域
1 // 获得scopeName对应的Scope对象
2 String scopeName = mbd.getScope();
3 final Scope scope = this.scopes.get(scopeName);
4 if (scope == null) {
5 throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
6 }
7 try {
8 /**
9 * 从指定的scope下创建bean
10 * {@link SimpleThreadScope#get方法}
11 */
12 Object scopedInstance = scope.get(beanName, () -> {
13 beforePrototypeCreation(beanName);
14 try {
15 return createBean(beanName, mbd, args);
16 } finally {
17 afterPrototypeCreation(beanName);
18 }
19 });
20 bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
21 } catch (IllegalStateException ex) {
22 throw new BeanCreationException(beanName,
23 "Scope '" + scopeName + "' is not active for the current thread; consider " +
24 "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
25 ex);
26 }
27 }
28 } catch (BeansException ex) {
29 cleanupAfterBeanCreationFailure(beanName);
30 throw ex;
31 }
其他作用域bean的创建过程与原型模式的流程一样,只是获取bean的方式变成了Scope#get(String name,ObjectFactory<?> objectFactory)。
1 // SimpleThreadScope
2 public Object get(String name, ObjectFactory<?> objectFactory) {
3 // 获取scope缓存
4 Map<String, Object> scope = this.threadScope.get();
5 Object scopedObject = scope.get(name);
6 if (scopedObject == null) {
7 // 这里getObject也是进行方法回调
8 scopedObject = objectFactory.getObject();
9 // 加入缓存
10 scope.put(name, scopedObject);
11 }
12 return scopedObject;
13 }
这里仅仅是Scope接口的一种实现,该接口还有其他多种实现,其具体源码可查看相应实现类:

至此,Bean加载的大致流程已分析完毕,当然本篇文章并未分析一个很重要的函数createBean,该函数留在后续的文章继续分析。
by Shawn Chen,2019.04.22,下午。