Bean 的加载
- bean 的加载远比bean 的解析复杂的多。
- 从
TestBean testBean = beanFactory.getBean("test", TestBean.class);
分析。
1 | //AbstractBeanFactory |
2 |
|
3 | public <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException { |
4 | return doGetBean(name, requiredType, null, false); |
5 | } |
6 | |
7 | "unchecked") ( |
8 | protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, |
9 | @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { |
10 | //提取对应的bean 名称 |
11 | final String beanName = transformedBeanName(name); |
12 | Object bean; |
13 | /** |
14 | * 检查缓存中或者实例工厂中是否有对应的实例 |
15 | * 首先使用这段代码的原因: |
16 | * 在创建bean 的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,Spring创建bean的原则是不等bean创建完成 |
17 | * 就会创建bean的ObjectFactory 提早曝光,即将ObjectFactory 加入到缓存中,一旦下个bean创建的时候,需要依赖上一个bean的时候,则直接使用beanFactory |
18 | */ |
19 | // 直接从缓存或者singletonFactories中的ObjectFactory中获取 |
20 | // Eagerly check singleton cache for manually registered singletons. |
21 | Object sharedInstance = getSingleton(beanName); |
22 | if (sharedInstance != null && args == null) { |
23 | if (logger.isDebugEnabled()) { |
24 | if (isSingletonCurrentlyInCreation(beanName)) { |
25 | logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + |
26 | "' that is not fully initialized yet - a consequence of a circular reference"); |
27 | } |
28 | else { |
29 | logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); |
30 | } |
31 | } |
32 | // 返回需要创建的实例。有时候诸如BeanFactory的情况返回的实例不是实例本身,而是工厂方法创建的实例 |
33 | bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); |
34 | } |
35 | |
36 | else { |
37 | //只有在单例情况才会尝试解决循环依赖, |
38 | //原型模式情况下,才会存在 A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会因为A还没有创建完的时候因为因为对于B的创建再次返回创建A, |
39 | //造成循环依赖,也就是下面的情况 |
40 | // Fail if we're already creating this bean instance: |
41 | // We're assumably within a circular reference. |
42 | if (isPrototypeCurrentlyInCreation(beanName)) { |
43 | throw new BeanCurrentlyInCreationException(beanName); |
44 | } |
45 | // Check if bean definition exists in this factory. |
46 | BeanFactory parentBeanFactory = getParentBeanFactory(); |
47 | //如果beanDefinintionMap(已经加载的类中)中不包括beanName则尝试从parentBeanFactory中检测 |
48 | if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { |
49 | // Not found -> check parent. |
50 | String nameToLookup = originalBeanName(name); |
51 | if (parentBeanFactory instanceof AbstractBeanFactory) { |
52 | return ((AbstractBeanFactory) parentBeanFactory).doGetBean( |
53 | nameToLookup, requiredType, args, typeCheckOnly); |
54 | } |
55 | //递归到BeanFactory中寻找 |
56 | else if (args != null) { |
57 | // Delegation to parent with explicit args. |
58 | return (T) parentBeanFactory.getBean(nameToLookup, args); |
59 | } |
60 | else { |
61 | // No args -> delegate to standard getBean method. |
62 | return parentBeanFactory.getBean(nameToLookup, requiredType); |
63 | } |
64 | } |
65 | //如果不是做类型检查,而是创建bean,则需要记录,将该bean标记为已创建 |
66 | if (!typeCheckOnly) { |
67 | markBeanAsCreated(beanName); |
68 | } |
69 | try { |
70 | //将存储xml配置文件的GernericBeanDefiniton转换为RootBeanDefinition,如果指定BeanDefinition是子bean的话同时会合并父类的相关属性 |
71 | final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); |
72 | checkMergedBeanDefinition(mbd, beanName, args); |
73 | //若存在依赖则需要递归实例化依赖的bean |
74 | // Guarantee initialization of beans that the current bean depends on. |
75 | String[] dependsOn = mbd.getDependsOn(); |
76 | if (dependsOn != null) { |
77 | for (String dep : dependsOn) { |
78 | if (isDependent(beanName, dep)) { |
79 | throw new BeanCreationException(mbd.getResourceDescription(), beanName, |
80 | "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); |
81 | } |
82 | //缓存依赖调用 |
83 | registerDependentBean(dep, beanName); |
84 | try { |
85 | getBean(dep); |
86 | } |
87 | catch (NoSuchBeanDefinitionException ex) { |
88 | throw new BeanCreationException(mbd.getResourceDescription(), beanName, |
89 | "'" + beanName + "' depends on missing bean '" + dep + "'", ex); |
90 | } |
91 | } |
92 | } |
93 | //实例化完依赖的bean后变可以实例化mbd 本身了 |
94 | //singleton 实例化 |
95 | // Create bean instance. |
96 | if (mbd.isSingleton()) { |
97 | sharedInstance = getSingleton(beanName, () -> { |
98 | try { |
99 | return createBean(beanName, mbd, args); |
100 | } |
101 | catch (BeansException ex) { |
102 | // Explicitly remove instance from singleton cache: It might have been put there |
103 | // eagerly by the creation process, to allow for circular reference resolution. |
104 | // Also remove any beans that received a temporary reference to the bean. |
105 | destroySingleton(beanName); |
106 | throw ex; |
107 | } |
108 | }); |
109 | bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); |
110 | } |
111 | //原型模式 |
112 | else if (mbd.isPrototype()) { |
113 | // It's a prototype -> create a new instance. |
114 | Object prototypeInstance = null; |
115 | try { |
116 | beforePrototypeCreation(beanName); |
117 | prototypeInstance = createBean(beanName, mbd, args); |
118 | } |
119 | finally { |
120 | afterPrototypeCreation(beanName); |
121 | } |
122 | bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); |
123 | } |
124 | // 指定scope上实例化 |
125 | else { |
126 | String scopeName = mbd.getScope(); |
127 | final Scope scope = this.scopes.get(scopeName); |
128 | if (scope == null) { |
129 | throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); |
130 | } |
131 | try { |
132 | Object scopedInstance = scope.get(beanName, () -> { |
133 | beforePrototypeCreation(beanName); |
134 | try { |
135 | return createBean(beanName, mbd, args); |
136 | } |
137 | finally { |
138 | afterPrototypeCreation(beanName); |
139 | } |
140 | }); |
141 | bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); |
142 | } |
143 | catch (IllegalStateException ex) { |
144 | throw new BeanCreationException(beanName, |
145 | "Scope '" + scopeName + "' is not active for the current thread; consider " + |
146 | "defining a scoped proxy for this bean if you intend to refer to it from a singleton", |
147 | ex); |
148 | } |
149 | } |
150 | } |
151 | catch (BeansException ex) { |
152 | cleanupAfterBeanCreationFailure(beanName); |
153 | throw ex; |
154 | } |
155 | } |
156 | //检查需要的类型是否符合bean的实际类型 |
157 | // Check if required type matches the type of the actual bean instance. |
158 | if (requiredType != null && !requiredType.isInstance(bean)) { |
159 | try { |
160 | T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); |
161 | if (convertedBean == null) { |
162 | throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); |
163 | } |
164 | return convertedBean; |
165 | } |
166 | catch (TypeMismatchException ex) { |
167 | if (logger.isDebugEnabled()) { |
168 | logger.debug("Failed to convert bean '" + name + "' to required type '" + |
169 | ClassUtils.getQualifiedName(requiredType) + "'", ex); |
170 | } |
171 | throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); |
172 | } |
173 | } |
174 | return (T) bean; |
175 | } |
bean 的加载过程:
转换对应的beanName
参数中传入的beanName 可能是别名,也可能是FactoryBean,所以需要一系列的解析和转换:1. 除去FactoryBean 的修饰符,及 name="&aa",则首先会出去 & 而使 name = "aa"; 2. 取指定alias 所表示的最终beanName,eg:别名A 指向名称为B的bean则返回B;若A指向别名B,B指向别名为C的bean,则返回C;
尝试从缓存中加载单例
在spring 的容器中,单例bean 只会被创建一次,后续获取bean,就直接从单例缓存中获取。当然,这只是尝试加载。因为在spring创建bean的时候会存在依赖注入的情况,而在创建依赖的时候,为了避免循环依赖,在spring 中创建bean 的原则是不等bean创建完成将bean的ObjectFactory提早曝光加入到缓存中。一点下一个bean创建的时候要依赖上一个bean则直接使用ObjectFactory
bean 的实例化
从缓存中获取到的bean是原始状态,还需要对bean进行实例化。eg:我们要对工厂bean进行处理,那么缓存中获取到的是工厂bean的初始状态,但我们真正需要的是工厂bean中定义的factory-method 方法中返回的bean,而getObjectForBeanInstance就是完成这个工作的。
原型模式的依赖检查
只有单利模式会处理循环依赖问题
检查parentBeanFactory
- 缓存中没有数据的话就从父类工长去加载了。
将存储xml 配置文件的GerenicBeanDefinition 转换为 RootBeanDefinition
将的GerenicBeanDefinition转换为RootBeanDefinition,同时,如果父类bean不为空的话,则合并父类的属性。
寻找依赖
spring 在加载bean的时候,会优先加载该bean 所依赖的bean
针对不同的scope进行bean的创建
- 如果不指定,则默认 scope 是singleton
- 如果配置则按照配置来创建
类型转换
FacoryBean 的使用
- spring 通过反射机制利用bean的class属性指定实现类来实例化bean。用户可以通过实现FactoryBean 自定义实例化bean的逻辑。
- FactoryBean 在spring中占有很重要的地位,spring自身就有70多个FactoryBean的实现.
1
public interface FactoryBean<T> {
2
//返回由BeanFactory 创建的bean实例。如果isSingleton 是true,则该实例会放到spring容器的单实例缓存中
3
4
T getObject() throws Exception;
5
// 返回工厂bean创建的bean 的类型
6
7
Class<?> getObjectType();
8
//判断该工厂创建实例bean的作用域
9
default boolean isSingleton() {
10
return true;
11
}
12
}
缓存中获取单例bean
1 | //DefaultSingletonBeanRegistry |
2 | |
3 | |
4 | public Object getSingleton(String beanName) { |
5 | //参数true设置表示允许早期依赖 |
6 | return getSingleton(beanName, true); |
7 | } |
8 | |
9 | protected Object getSingleton(String beanName, boolean allowEarlyReference) { |
10 | //检查缓存中是否存在实例 |
11 | Object singletonObject = this.singletonObjects.get(beanName); |
12 | if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { |
13 | // 如果不存在,而且当前的bean在创建中,锁定全局变量进行处理 |
14 | synchronized (this.singletonObjects) { |
15 | singletonObject = this.earlySingletonObjects.get(beanName); |
16 | if (singletonObject == null && allowEarlyReference) { |
17 | //当某些方法需要提前初始化的时候,则会调用addSingletonFactory方法将对应的ObjectFactory初始化策略存储在earlySingletonFactories,所以此处可以取singletonFactory |
18 | ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); |
19 | if (singletonFactory != null) { |
20 | //earlySingletonObjects 和 singletonFactories 两个不能同时存在 |
21 | singletonObject = singletonFactory.getObject(); |
22 | this.earlySingletonObjects.put(beanName, singletonObject); |
23 | this.singletonFactories.remove(beanName); |
24 | } |
25 | } |
26 | } |
27 | } |
28 | return singletonObject; |
29 | } |
上面方法中四个map,解释如下:
- singletonObjects 用于保存beanName 和创建bean 实例之间的关系。 bean name -> bean instance
- singletonFactories 用于保存beanName 和创建 bean的工厂之间的关系。 bean name -> ObjectFactory
- earlySingletonObjects 保存beanName 和创建bean 实例之间的关系,于singletonObjects的不同之处是,earlySingletonObjects中的bean 对象还在创建过程中,就可以通过getBean 方法获取到了,目的是用来检测循环依赖。
- registedSingletons: 用来保存当前所有已经注册的bean
从bean 的实例中获取对象
AbstractBeanFactory#getObjectForBeanInstance
用来检查bean 的正确性:检查当前的bean 是否是FactoryBean 类型的bean,如果是,则需要调用 FactoryBean#getObject作为返回值
1 | //AbstractBeanFactory |
2 | protected Object getObjectForBeanInstance( |
3 | Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { |
4 | //如果指定的bean是工厂相关(以&为前缀) |
5 | // Don't let calling code try to dereference the factory if the bean isn't a factory. |
6 | if (BeanFactoryUtils.isFactoryDereference(name)) { |
7 | if (beanInstance instanceof NullBean) { |
8 | return beanInstance; |
9 | } |
10 | // beanInstance 不是FacoryBean 类型的,则抛出指定异常 |
11 | if (!(beanInstance instanceof FactoryBean)) { |
12 | throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass()); |
13 | } |
14 | } |
15 | |
16 | // Now we have the bean instance, which may be a normal bean or a FactoryBean. |
17 | // If it's a FactoryBean, we use it to create a bean instance, unless the |
18 | // caller actually wants a reference to the factory. |
19 | // 如果不是FacotryBean 类型的 或者调用这想返回FactoryBean类型的bean(name 以&符号开头,如:&aa)则直接返回instance |
20 | if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { |
21 | return beanInstance; |
22 | } |
23 | // 加载FactoryBean |
24 | Object object = null; |
25 | if (mbd == null) { |
26 | //尝试从缓存中获取 |
27 | object = getCachedObjectForFactoryBean(beanName); |
28 | } |
29 | if (object == null) { |
30 | //此处确定beanInstance一定为FactoryBean类型的 |
31 | // Return bean instance from factory. |
32 | FactoryBean<?> factory = (FactoryBean<?>) beanInstance; |
33 | //containsBeanDefinition方法检查BeanDefinitionMap中是否存在指定beanName 的bean |
34 | // Caches object obtained from FactoryBean if it is a singleton. |
35 | if (mbd == null && containsBeanDefinition(beanName)) { |
36 | // 如果存在将 GerenicBeanDefinition 转换为RootBeanDefinition,如果该bean是子类的话,会合并父类的属性 |
37 | mbd = getMergedLocalBeanDefinition(beanName); |
38 | } |
39 | //是否是用户定义的而不是应用程序本身的 |
40 | boolean synthetic = (mbd != null && mbd.isSynthetic()); |
41 | object = getObjectFromFactoryBean(factory, beanName, !synthetic); |
42 | } |
43 | return object; |
44 | } |
以上代码的工作:
- 对FactoryBean 正确性的验证
- 对非FactoryBean 不做任何处理,直接返回
- 对bean进行转换
- 将从Factory中解析bean的工作委托给getObjectFromFactoryBean
AbstractBeanFactory#getObjectFromFactoryBean
方法分析
AbstractBeanFactory#getObjectFromFactoryBean 最终调用的是FactoryBeanRegistrySupport
1 | //FactoryBeanRegistrySupport |
2 | protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { |
3 | if (factory.isSingleton() && containsSingleton(beanName)) { |
4 | synchronized (getSingletonMutex()) { |
5 | Object object = this.factoryBeanObjectCache.get(beanName); |
6 | if (object == null) { |
7 | object = doGetObjectFromFactoryBean(factory, beanName); |
8 | // Only post-process and store if not put there already during getObject() call above |
9 | // (e.g. because of circular reference processing triggered by custom getBean calls) |
10 | Object alreadyThere = this.factoryBeanObjectCache.get(beanName); |
11 | if (alreadyThere != null) { |
12 | object = alreadyThere; |
13 | } |
14 | else { |
15 | if (shouldPostProcess) { |
16 | if (isSingletonCurrentlyInCreation(beanName)) { |
17 | // Temporarily return non-post-processed object, not storing it yet.. |
18 | return object; |
19 | } |
20 | //回调函数,在bean 创建前标记为正在创建(Callback before singleton creation.) |
21 | beforeSingletonCreation(beanName); |
22 | try { |
23 | //调用objectFactory的后处理器 |
24 | object = postProcessObjectFromFactoryBean(object, beanName); |
25 | } |
26 | catch (Throwable ex) { |
27 | throw new BeanCreationException(beanName, |
28 | "Post-processing of FactoryBean's singleton object failed", ex); |
29 | } |
30 | finally { |
31 | afterSingletonCreation(beanName); |
32 | } |
33 | } |
34 | if (containsSingleton(beanName)) { |
35 | this.factoryBeanObjectCache.put(beanName, object); |
36 | } |
37 | } |
38 | } |
39 | return object; |
40 | } |
41 | } |
42 | else { |
43 | Object object = doGetObjectFromFactoryBean(factory, beanName); |
44 | if (shouldPostProcess) { |
45 | try { |
46 | object = postProcessObjectFromFactoryBean(object, beanName); |
47 | } |
48 | catch (Throwable ex) { |
49 | throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex); |
50 | } |
51 | } |
52 | return object; |
53 | } |
54 | } |
55 | // 从FactoryBean 获取bean 的实际方法 |
56 | private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName) |
57 | throws BeanCreationException { |
58 | Object object; |
59 | try { |
60 | if (System.getSecurityManager() != null) { |
61 | AccessControlContext acc = getAccessControlContext(); |
62 | try { |
63 | object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc); |
64 | } |
65 | catch (PrivilegedActionException pae) { |
66 | throw pae.getException(); |
67 | } |
68 | } |
69 | else { |
70 | object = factory.getObject(); |
71 | } |
72 | } |
73 | catch (FactoryBeanNotInitializedException ex) { |
74 | throw new BeanCurrentlyInCreationException(beanName, ex.toString()); |
75 | } |
76 | catch (Throwable ex) { |
77 | throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex); |
78 | } |
79 | // Do not accept a null value for a FactoryBean that's not fully |
80 | // initialized yet: Many FactoryBeans just return null then. |
81 | if (object == null) { |
82 | if (isSingletonCurrentlyInCreation(beanName)) { |
83 | throw new BeanCurrentlyInCreationException( |
84 | beanName, "FactoryBean which is currently in creation returned null from getObject"); |
85 | } |
86 | object = new NullBean(); |
87 | } |
88 | return object; |
89 | } |
AbstractAutowireCapableBeanFactory#postProcessObjectFromFactoryBean 方法的作用
1 |
|
2 | protected Object postProcessObjectFromFactoryBean(Object object, String beanName) { |
3 | return applyBeanPostProcessorsAfterInitialization(object, beanName); |
4 | } |
5 | |
6 |
|
7 | public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) |
8 | throws BeansException { |
9 | |
10 | Object result = existingBean; |
11 | for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { |
12 | Object current = beanProcessor.postProcessAfterInitialization(result, beanName); |
13 | if (current == null) { |
14 | return result; |
15 | } |
16 | result = current; |
17 | } |
18 | return result; |
19 | } |
在bean 创建完成前可以对bean做特殊的处理。例如增加自己特有的业务逻辑。 主要是BeanPostProcessor 的应用,后期分析。
获取单例
如果从缓存中获取不到bean,则需要从头开始加载singleton,spring是利用重载的方式实现bean的加载过程
1 | //DefaultSingletonBeanRegistry |
2 | public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { |
3 | Assert.notNull(beanName, "Bean name must not be null"); |
4 | //操作全局变量,所以需要同步 |
5 | synchronized (this.singletonObjects) { |
6 | //首先检查bean 是否已经创建过。 |
7 | Object singletonObject = this.singletonObjects.get(beanName); |
8 | //singletonObject 为空,说明没有创建过,则开始创建 |
9 | if (singletonObject == null) { |
10 | if (this.singletonsCurrentlyInDestruction) { |
11 | throw new BeanCreationNotAllowedException(beanName, |
12 | "Singleton bean creation not allowed while singletons of this factory are in destruction " + |
13 | "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); |
14 | } |
15 | if (logger.isDebugEnabled()) { |
16 | logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); |
17 | } |
18 | beforeSingletonCreation(beanName); |
19 | boolean newSingleton = false; |
20 | boolean recordSuppressedExceptions = (this.suppressedExceptions == null); |
21 | if (recordSuppressedExceptions) { |
22 | this.suppressedExceptions = new LinkedHashSet<>(); |
23 | } |
24 | try { |
25 | singletonObject = singletonFactory.getObject(); |
26 | newSingleton = true; |
27 | } |
28 | catch (IllegalStateException ex) { |
29 | // Has the singleton object implicitly appeared in the meantime -> |
30 | // if yes, proceed with it since the exception indicates that state. |
31 | singletonObject = this.singletonObjects.get(beanName); |
32 | if (singletonObject == null) { |
33 | throw ex; |
34 | } |
35 | } |
36 | catch (BeanCreationException ex) { |
37 | if (recordSuppressedExceptions) { |
38 | for (Exception suppressedException : this.suppressedExceptions) { |
39 | ex.addRelatedCause(suppressedException); |
40 | } |
41 | } |
42 | throw ex; |
43 | } |
44 | finally { |
45 | if (recordSuppressedExceptions) { |
46 | this.suppressedExceptions = null; |
47 | } |
48 | afterSingletonCreation(beanName); |
49 | } |
50 | if (newSingleton) { |
51 | //加入到混存 |
52 | addSingleton(beanName, singletonObject); |
53 | } |
54 | } |
55 | return singletonObject; |
56 | } |
57 | } |
以上方法的作用:
- 检查缓存是否加载过
- 若没有加载,则修改beanName 的加载状态
- 加载单利前记录加载状态
- 通过调用参数传入的ObjectFactory 的个体object方法实例化bean。
- 加载代理方法的处理方法调用
- 将结果加入缓存,并删除bean加载过程中记录的各种辅助状态。
- 返回处理结果。
准备创建bean
通过反spring 源码,我们总结出了一个经验:真正干活的函数其实是以 do 开头的方法。
1 | //AbstractBeanFactory#doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) |
2 | if (mbd.isSingleton()) { |
3 | sharedInstance = getSingleton(beanName, () -> { |
4 | try { |
5 | return createBean(beanName, mbd, args); |
6 | } |
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 | destroySingleton(beanName); |
12 | throw ex; |
13 | } |
14 | }); |
15 | bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); |
16 | } |
1 | //AbstractAutowireCapableBeanFactory |
2 | |
3 | protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) |
4 | throws BeanCreationException { |
5 | if (logger.isDebugEnabled()) { |
6 | logger.debug("Creating instance of bean '" + beanName + "'"); |
7 | } |
8 | RootBeanDefinition mbdToUse = mbd; |
9 | //锁定class,根据设置的class属性或者根据className来解析Class |
10 | // Make sure bean class is actually resolved at this point, and |
11 | // clone the bean definition in case of a dynamically resolved Class |
12 | // which cannot be stored in the shared merged bean definition. |
13 | Class<?> resolvedClass = resolveBeanClass(mbd, beanName); |
14 | if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { |
15 | mbdToUse = new RootBeanDefinition(mbd); |
16 | mbdToUse.setBeanClass(resolvedClass); |
17 | } |
18 | //验证及准备覆盖的方法 |
19 | // Prepare method overrides. |
20 | try { |
21 | mbdToUse.prepareMethodOverrides(); |
22 | } |
23 | catch (BeanDefinitionValidationException ex) { |
24 | throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), |
25 | beanName, "Validation of method overrides failed", ex); |
26 | } |
27 | |
28 | try { |
29 | //给BeanPostProcessors 一个机会来返回代理来代替真正的实例 |
30 | // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. |
31 | Object bean = resolveBeforeInstantiation(beanName, mbdToUse); |
32 | if (bean != null) { |
33 | return bean; |
34 | } |
35 | } |
36 | catch (Throwable ex) { |
37 | throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, |
38 | "BeanPostProcessor before instantiation of bean failed", ex); |
39 | } |
40 | |
41 | try { |
42 | Object beanInstance = doCreateBean(beanName, mbdToUse, args); |
43 | if (logger.isDebugEnabled()) { |
44 | logger.debug("Finished creating instance of bean '" + beanName + "'"); |
45 | } |
46 | return beanInstance; |
47 | } |
48 | catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { |
49 | // A previously detected exception with proper bean creation context already, |
50 | // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry. |
51 | throw ex; |
52 | } |
53 | catch (Throwable ex) { |
54 | throw new BeanCreationException( |
55 | mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); |
56 | } |
57 | } |
以上方法的作用:
- 根据设置的class属性及className来解析class
- 对override属性进行标记及验证
处理spring中的lookup-method 和replaced-method的。这两个配置的加载其实就是将配置统一存在BeanDefinition中的methodOverrides属性里。此处的处理,就是对methodOverrides的处理。 - 应用初始化前的后处理器,解析指定bean是否存在初始化前的短路操作。
- 创建bean
Ovveride属性处理
AbstractBeanDefinition 类的prepareMethodOverrides方法:
1 | public void prepareMethodOverrides() throws BeanDefinitionValidationException { |
2 | // Check that lookup methods exists. |
3 | if (hasMethodOverrides()) { |
4 | Set<MethodOverride> overrides = getMethodOverrides().getOverrides(); |
5 | synchronized (overrides) { |
6 | for (MethodOverride mo : overrides) { |
7 | prepareMethodOverride(mo); |
8 | } |
9 | } |
10 | } |
11 | } |
12 | protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException { |
13 | //获取对应类中对应方法名的个数 |
14 | int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName()); |
15 | if (count == 0) { |
16 | throw new BeanDefinitionValidationException( |
17 | "Invalid method override: no method with name '" + mo.getMethodName() + |
18 | "' on class [" + getBeanClassName() + "]"); |
19 | } |
20 | else if (count == 1) { |
21 | //标记MethodOverride 暂未覆盖,避免参数类型检查的开销 |
22 | // Mark override as not overloaded, to avoid the overhead of arg type checking. |
23 | mo.setOverloaded(false); |
24 | } |
25 | } |
实例化前置处理
AOP 的功能在此处处理。
1 | //AbstractAutowireCapableBeanFactory |
2 |
|
3 | protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { |
4 | Object bean = null; |
5 | //如果bean 尚未被解析 |
6 | if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { |
7 | // Make sure bean class is actually resolved at this point. |
8 | if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { |
9 | Class<?> targetType = determineTargetType(beanName, mbd); |
10 | if (targetType != null) { |
11 | //实例化前的后处理器 |
12 | bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); |
13 | if (bean != null) { |
14 | //实例化后的后处理器 |
15 | bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); |
16 | } |
17 | } |
18 | } |
19 | mbd.beforeInstantiationResolved = (bean != null); |
20 | } |
21 | return bean; |
22 | } |
实例化前的后处理器应用
1
//AbstractAutowireCapableBeanFactory
2
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
3
for (BeanPostProcessor bp : getBeanPostProcessors()) {
4
if (bp instanceof InstantiationAwareBeanPostProcessor) {
5
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
6
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
7
if (result != null) {
8
return result;
9
}
10
}
11
}
12
return null;
13
}
作用:
给子类修改beanDefinition的机会,经过此处后,bean可能就不是我们认为的bean了,而是或许成为了一个经过处理的代理bean,也可能是cjlib生成的。也可能是其他技术生成的。- 实例化后的后处理器的应用
1
2
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
3
throws BeansException {
4
Object result = existingBean;
5
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
6
Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
7
if (current == null) {
8
return result;
9
}
10
result = current;
11
}
12
return result;
13
}
- 实例化后的后处理器的应用
循环依赖问题
循环依赖是无法解决的,除非有最终方案,否则就是死循环,最终导致内存溢出的错误。
Spring 如何解决循环依赖问题
spring 的注入方式分为两类:构造注入,setter注入。分别说明。
构造循环依赖 (无法解决)
表示通过构造器注入构成的循环依赖是无法解决的。只能抛出BeanCurrentlyIncreationException。setter 循环依赖(只能解决单例模式
scope =singleton
)
对于setter 注入造成的依赖是通过spring 容器提前暴露刚完成构造器注入但未完成其他步骤(如setter注入)的bean来完成的。且只能解决单例作用域的循环依赖问题。通过提前暴露一个单例工厂方法,从而使得其他bean能应用到该bean。1
addSingletonFactory(beanName, new ObjecttFactory(){
2
public Object getObject()throws BeansException{
3
return getEarlyBeanReference(beanName,mbd,bean);
4
}
5
})
具体步骤:(无法解决)
- spring 创建单例“testA” bean,首先依据无参构造构造器创建bean,并暴露一个“ObjectFactory”用于返回一个提前暴露 一个创建中的bean,并将 “testA” 标识放到当前创建bean池。然后进行setter 注入 “testB”
- spring 首先依据无参构造器创建bean “testB”,并暴露一个“ObjectFactory”,用于提前暴露一个创建中的bean,并将并“testB” 放到当前创建bean池,然后进行setter注入“testC”
- spring 依据无参构造器创建 bean “testC”,并暴露一个“ObjectFactory”用于提前暴露一个创建中的bean “testC”, 并将“testC” 放到当前创建bean池,然后setter 注入 “testA”.注入“TestA” 时,由于提前暴露了”ObjectFactory” 工厂,从而使得他返回提前暴露一个创建中的bean。
- 最后依次完成 “testB” 和”testA” 的setter注入。
propertype 范围的依赖处理
对于 “propertype” 作用域bean,spring 容器无法完成依赖注入。因为spring容器不进行缓存 “propertype” 作用域的bean,因此无法提前暴露一个创建中的bean。
总结
- spring中,只有
scope=singleton
(单例模式),通过setter 注入的方式解决循环依赖问题。 - 对于单例模式“singleton”作用域的bean,可以通过 “setterAllowCirclularReferences(false)” 来禁用循环引用。
创建bean
当经历过resolveBeforeInstantiation 方法后,程序有两个选择,如果创建了代理或者重写了InstatiationAwareBeanPostProcessor 的postProcessBeforeInstatiation方法并且在 postProcessBeforeInstatiation中改变了bean,则直接返回就可以了,否则则需要常规的bean 创建过程。
1 | //AbstractAutowireCapableBeanFactory |
2 | protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) |
3 | throws BeanCreationException { |
4 | // Instantiate the bean. |
5 | BeanWrapper instanceWrapper = null; |
6 | // 1. 如果是单例,首先清除缓存 |
7 | if (mbd.isSingleton()) { |
8 | instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); |
9 | } |
10 | //2. 实例化bean,将BeanDefinition转换为 BeanWrapper |
11 | if (instanceWrapper == null) { |
12 | //根据指定bean使用对应的策略创建新的实例,如:工厂方法、构造参数注入,简单初始化 |
13 | instanceWrapper = createBeanInstance(beanName, mbd, args); |
14 | } |
15 | final Object bean = instanceWrapper.getWrappedInstance(); |
16 | Class<?> beanType = instanceWrapper.getWrappedClass(); |
17 | if (beanType != NullBean.class) { |
18 | mbd.resolvedTargetType = beanType; |
19 | } |
20 | // Allow post-processors to modify the merged bean definition. |
21 | synchronized (mbd.postProcessingLock) { |
22 | if (!mbd.postProcessed) { |
23 | try { |
24 | //3. MergedBeanDefinitionPostProcessor 的应用。bean合并后的处理,Autowired注解正式通过此方法实现诸如类型的预先解析 |
25 | applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); |
26 | } |
27 | catch (Throwable ex) { |
28 | throw new BeanCreationException(mbd.getResourceDescription(), beanName, |
29 | "Post-processing of merged bean definition failed", ex); |
30 | } |
31 | mbd.postProcessed = true; |
32 | } |
33 | } |
34 | //4. 依赖处理 |
35 | //单例模式允许循环依赖。 |
36 | //提早曝光条件:单例&允许循环依赖&当前bean正在创建中,检查循环依赖 |
37 | // Eagerly cache singletons to be able to resolve circular references |
38 | // even when triggered by lifecycle interfaces like BeanFactoryAware. |
39 | boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && |
40 | isSingletonCurrentlyInCreation(beanName)); |
41 | if (earlySingletonExposure) { |
42 | if (logger.isDebugEnabled()) { |
43 | logger.debug("Eagerly caching bean '" + beanName + |
44 | "' to allow for resolving potential circular references"); |
45 | } |
46 | // 为了避免循环依赖,可以在bean初始化完成前将创建 |
47 | addSingletonFactory(beanName, () -> |
48 | //对bean再一次依赖引用,主要是smartInstatiationAware beanPostProcessor, |
49 | //其中我们熟知的aop就是在这里将 advice 动态的织入bean中。如果没有,则不做任何处理,直接返回,不做任何处理 |
50 | getEarlyBeanReference(beanName, mbd, bean)); |
51 | } |
52 | // Initialize the bean instance. |
53 | Object exposedObject = bean; |
54 | try { |
55 | //5. 属性处理 |
56 | //对bean进行填充,将各个属性注入。其中可能存在依赖其他bean的属性,会递归初始化依赖bean |
57 | populateBean(beanName, mbd, instanceWrapper); |
58 | // 调用初始化方法,如:init-method |
59 | exposedObject = initializeBean(beanName, exposedObject, mbd); |
60 | } |
61 | catch (Throwable ex) { |
62 | if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { |
63 | throw (BeanCreationException) ex; |
64 | } |
65 | else { |
66 | throw new BeanCreationException( |
67 | mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); |
68 | } |
69 | } |
70 | //6. 循环依赖的检查 |
71 | if (earlySingletonExposure) { |
72 | Object earlySingletonReference = getSingleton(beanName, false); |
73 | //只有循环依赖的情况下,earlySingletonReference才不会为空 |
74 | if (earlySingletonReference != null) { |
75 | //exposedObject没有在初始化方法中改变,即没有被增强 |
76 | if (exposedObject == bean) { |
77 | exposedObject = earlySingletonReference; |
78 | } |
79 | else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { |
80 | String[] dependentBeans = getDependentBeans(beanName); |
81 | Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); |
82 | //检查依赖 |
83 | for (String dependentBean : dependentBeans) { |
84 | if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { |
85 | actualDependentBeans.add(dependentBean); |
86 | } |
87 | } |
88 | // bean 创建后,其依赖是一定创建了的, |
89 | // bean 创建后,actualDependentBeans没有为空,则说明bean创建后,其依赖的bean没有完全创建,说明依赖bean之间存在虚幻依赖。 |
90 | if (!actualDependentBeans.isEmpty()) { |
91 | throw new BeanCurrentlyInCreationException(beanName, |
92 | "Bean with name '" + beanName + "' has been injected into other beans [" + |
93 | StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + |
94 | "] in its raw version as part of a circular reference, but has eventually been " + |
95 | "wrapped. This means that said other beans do not use the final version of the " + |
96 | "bean. This is often the result of over-eager type matching - consider using " + |
97 | "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); |
98 | } |
99 | } |
100 | } |
101 | } |
102 | //7. 注册 disposableBean |
103 | //如果配置了destroy-method 方法,这里会注册,在bean销毁时会调用 |
104 | // Register bean as disposable. |
105 | try { |
106 | //依据scope 注册bean |
107 | registerDisposableBeanIfNecessary(beanName, bean, mbd); |
108 | } |
109 | catch (BeanDefinitionValidationException ex) { |
110 | throw new BeanCreationException( |
111 | mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); |
112 | } |
113 | // 8. 返回 |
114 | return exposedObject; |
115 | } |
一下对bean的创建过程详细分析:
创建bean的实例
1 | //ConstructorResolver |
2 | protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { |
3 | // Make sure bean class is actually resolved at this point. |
4 | // 解析class |
5 | Class<?> beanClass = resolveBeanClass(mbd, beanName); |
6 | if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { |
7 | throw new BeanCreationException(mbd.getResourceDescription(), beanName, |
8 | "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); |
9 | } |
10 | // 如果 模板中 supplier不为空,则从 supplier中获取 |
11 | Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); |
12 | if (instanceSupplier != null) { |
13 | return obtainFromSupplier(instanceSupplier, beanName); |
14 | } |
15 | // 如果工厂方法不为空,则使用工厂方法创建 |
16 | if (mbd.getFactoryMethodName() != null) { |
17 | return instantiateUsingFactoryMethod(beanName, mbd, args); |
18 | } |
19 | // Shortcut when re-creating the same bean... |
20 | boolean resolved = false; |
21 | boolean autowireNecessary = false; |
22 | if (args == null) { |
23 | // 一个类有多个构造函数,每个构造函数有不同的参数,所以调用前需要根据参数锁定构造参数或者对应的工厂方法 |
24 | synchronized (mbd.constructorArgumentLock) { |
25 | if (mbd.resolvedConstructorOrFactoryMethod != null) { |
26 | resolved = true; |
27 | autowireNecessary = mbd.constructorArgumentsResolved; |
28 | } |
29 | } |
30 | } |
31 | //如果已经解析过,则使用解析好的构造函数方法,不需要再次锁定 |
32 | if (resolved) { |
33 | if (autowireNecessary) { |
34 | //构造参数自动注入 |
35 | return autowireConstructor(beanName, mbd, null, null); |
36 | } |
37 | else { |
38 | //默认构造函数构造 |
39 | return instantiateBean(beanName, mbd); |
40 | } |
41 | } |
42 | //根据参数解析构造函数 |
43 | // Candidate constructors for autowiring? |
44 | Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); |
45 | if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || |
46 | mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { |
47 | //构造函数自动注入 |
48 | return autowireConstructor(beanName, mbd, ctors, args); |
49 | } |
50 | //使用指定的默认构造函数解析. |
51 | // Preferred constructors for default construction? |
52 | ctors = mbd.getPreferredConstructors(); |
53 | if (ctors != null) { |
54 | return autowireConstructor(beanName, mbd, ctors, null); |
55 | } |
56 | //使用默认构造函数 |
57 | // No special handling: simply use no-arg constructor. |
58 | return instantiateBean(beanName, mbd); |
59 | } |
具体逻辑:
1. 如果 RootbeanDefinition
中存在 factoryMethodName 属性,或者说在配置文件中配置了factory-method, 那么spring 会尝试使用instantiateUsingFactoryMethod 方法根据RootBeanDefinition 中的配置生成bean的实例.
2. 解析构造函数并根据构造函数实例化. 一个bean中可能有多个构造函数,而每个构造函数的参数不同,spring 在解析的过程中需要判断最终会使用哪个构造函数. 但是,判断过程中比较耗性能,所以spring 采用了缓存机制,如果已经解析过,则不需要重复解析而是使用RootBeanDefinition 中的属性
resolvedConstructorOrFactoryMethod 缓存直接去创建.否则,需要再次解析.并将结果添加到 resolvedConstructorOrFactoryMethod 中.
autowireConstructor
对于实例的创建spring中分成了两种情况,一种是通用实例化,另一种是带有参数的实例化. 带有参数的实例化过程相当 复杂,因为存在着不确定性,所以在判断对应参数上做了大量工作.
1 | public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, |
2 | @Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) { |
3 | |
4 | BeanWrapperImpl bw = new BeanWrapperImpl(); |
5 | this.beanFactory.initBeanWrapper(bw); |
6 | |
7 | Constructor<?> constructorToUse = null; |
8 | ArgumentsHolder argsHolderToUse = null; |
9 | Object[] argsToUse = null; |
10 | //explicitArgs 通过getBean方法传入 |
11 | //如果getBean 方法调用的时候指定方法参数那么直接使用. |
12 | if (explicitArgs != null) { |
13 | argsToUse = explicitArgs; |
14 | } |
15 | else { |
16 | //如果在调用getBean 的时候没有指定,则尝试从配置文件中解析获取. |
17 | Object[] argsToResolve = null; |
18 | //尝试从缓存中获取 |
19 | synchronized (mbd.constructorArgumentLock) { |
20 | constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod; |
21 | if (constructorToUse != null && mbd.constructorArgumentsResolved) { |
22 | // Found a cached constructor... |
23 | // 在缓存中获取 |
24 | argsToUse = mbd.resolvedConstructorArguments; |
25 | if (argsToUse == null) { |
26 | //配置的构造参数 |
27 | argsToResolve = mbd.preparedConstructorArguments; |
28 | } |
29 | } |
30 | } |
31 | //如果缓存中存在 |
32 | if (argsToResolve != null) { |
33 | //解析参数类型,如给定方法的构造参数A(int,int), 则通过此方法后就会把配置文件中 的("1","1")转换为(1,1) |
34 | //缓存中的值可能是原始值,也可能是最终值 |
35 | argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true); |
36 | } |
37 | } |
38 | //如果没有缓存 |
39 | if (constructorToUse == null || argsToUse == null) { |
40 | // Take specified constructors, if any. |
41 | // 使用可用的候选构造方法集合 |
42 | Constructor<?>[] candidates = chosenCtors; |
43 | if (candidates == null) { |
44 | Class<?> beanClass = mbd.getBeanClass(); |
45 | try { |
46 | candidates = (mbd.isNonPublicAccessAllowed() ? |
47 | beanClass.getDeclaredConstructors() : beanClass.getConstructors()); |
48 | } |
49 | catch (Throwable ex) { |
50 | throw new BeanCreationException(mbd.getResourceDescription(), beanName, |
51 | "Resolution of declared constructors on bean Class [" + beanClass.getName() + |
52 | "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex); |
53 | } |
54 | } |
55 | //如果只有一个候选构造方法,同时显性参数为空,配置文件中也没有构造参数,则说明为为无参构造函数. |
56 | if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) { |
57 | Constructor<?> uniqueCandidate = candidates[0]; |
58 | if (uniqueCandidate.getParameterCount() == 0) { |
59 | synchronized (mbd.constructorArgumentLock) { |
60 | mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate; |
61 | mbd.constructorArgumentsResolved = true; |
62 | mbd.resolvedConstructorArguments = EMPTY_ARGS; |
63 | } |
64 | //构建无参的实例,并加入到beanWapper 中 |
65 | bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS)); |
66 | return bw; |
67 | } |
68 | } |
69 | //需要解析构造函数 |
70 | // Need to resolve the constructor. |
71 | boolean autowiring = (chosenCtors != null || |
72 | mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR); |
73 | ConstructorArgumentValues resolvedValues = null; |
74 | //设置能解析到的构造参数的数量 |
75 | int minNrOfArgs; |
76 | //显性指定的不为空,使用显性指定的,否则使用xml文件中的 |
77 | if (explicitArgs != null) { |
78 | minNrOfArgs = explicitArgs.length; |
79 | } |
80 | else { |
81 | ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues(); |
82 | resolvedValues = new ConstructorArgumentValues(); |
83 | //处理构造函数,此处可能会查找其他bean |
84 | minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues); |
85 | } |
86 | //排序给定的构造函数,public 的函数优先参数数量降序,非public的构造函数参数数量降序 |
87 | AutowireUtils.sortConstructors(candidates); |
88 | int minTypeDiffWeight = Integer.MAX_VALUE; |
89 | Set<Constructor<?>> ambiguousConstructors = null; |
90 | LinkedList<UnsatisfiedDependencyException> causes = null; |
91 | //选择构造函数 |
92 | for (Constructor<?> candidate : candidates) { |
93 | int parameterCount = candidate.getParameterCount(); |
94 | //如果已经找到选用的构造函数或者需要的构造参数小于当前的构造个数则终止,应为已经按照构造参数排序了 |
95 | if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) { |
96 | // Already found greedy constructor that can be satisfied -> |
97 | // do not look any further, there are only less greedy constructors left. |
98 | break; |
99 | } |
100 | //参数个数不相等 |
101 | if (parameterCount < minNrOfArgs) { |
102 | continue; |
103 | } |
104 | ArgumentsHolder argsHolder; |
105 | Class<?>[] paramTypes = candidate.getParameterTypes(); |
106 | //如果有参数则根据值构造对应参数的类型 |
107 | if (resolvedValues != null) { |
108 | try { |
109 | //解析注解的构造参数信息(jdk1.6 以后可以在构造函数中使用注解) |
110 | String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount); |
111 | if (paramNames == null) { |
112 | //获取参数名称搜索器 |
113 | ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer(); |
114 | if (pnd != null) { |
115 | //获取指定构造参数名称 |
116 | paramNames = pnd.getParameterNames(candidate); |
117 | } |
118 | } |
119 | //根据参数名称和数据类型创建持有者 |
120 | argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames, |
121 | getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1); |
122 | } |
123 | catch (UnsatisfiedDependencyException ex) { |
124 | if (logger.isTraceEnabled()) { |
125 | logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex); |
126 | } |
127 | // Swallow and try next constructor. |
128 | if (causes == null) { |
129 | causes = new LinkedList<>(); |
130 | } |
131 | causes.add(ex); |
132 | continue; |
133 | } |
134 | } |
135 | else { |
136 | //构造函数和getBean 方法传输的参数不相等 |
137 | // Explicit arguments given -> arguments length must match exactly. |
138 | if (parameterCount != explicitArgs.length) { |
139 | continue; |
140 | } |
141 | //依据传入的构造参数(没有构造参数) |
142 | argsHolder = new ArgumentsHolder(explicitArgs); |
143 | } |
144 | //探测是否有不确定性的构造函数存在,例如不同构造函数的参数为父子关系 |
145 | int typeDiffWeight = (mbd.isLenientConstructorResolution() ? |
146 | argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes)); |
147 | // Choose this constructor if it represents the closest match. |
148 | if (typeDiffWeight < minTypeDiffWeight) { |
149 | constructorToUse = candidate; |
150 | argsHolderToUse = argsHolder; |
151 | argsToUse = argsHolder.arguments; |
152 | minTypeDiffWeight = typeDiffWeight; |
153 | ambiguousConstructors = null; |
154 | } |
155 | else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) { |
156 | if (ambiguousConstructors == null) { |
157 | ambiguousConstructors = new LinkedHashSet<>(); |
158 | ambiguousConstructors.add(constructorToUse); |
159 | } |
160 | ambiguousConstructors.add(candidate); |
161 | } |
162 | } |
163 | if (constructorToUse == null) { |
164 | if (causes != null) { |
165 | UnsatisfiedDependencyException ex = causes.removeLast(); |
166 | for (Exception cause : causes) { |
167 | this.beanFactory.onSuppressedException(cause); |
168 | } |
169 | throw ex; |
170 | } |
171 | throw new BeanCreationException(mbd.getResourceDescription(), beanName, |
172 | "Could not resolve matching constructor " + |
173 | "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)"); |
174 | } |
175 | else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) { |
176 | throw new BeanCreationException(mbd.getResourceDescription(), beanName, |
177 | "Ambiguous constructor matches found in bean '" + beanName + "' " + |
178 | "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " + |
179 | ambiguousConstructors); |
180 | } |
181 | if (explicitArgs == null && argsHolderToUse != null) { |
182 | //将解析到的构造函数加入缓存 |
183 | argsHolderToUse.storeCache(mbd, constructorToUse); |
184 | } |
185 | } |
186 | Assert.state(argsToUse != null, "Unresolved constructor arguments"); |
187 | //将构造的实例加入beanWapper |
188 | bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse)); |
189 | return bw; |
190 | } |
主要逻辑:
构造函数参数的确定:
- 根据传入的参数 explicitArgs 判断(getBean 方法传入)
- 缓存中获取
- 构造方法的注解中获取(jdk 1.6 新增)
- 配置文件获取
构造函数的确定
根据参数个数匹配,在匹配之前,要对找到的构造方法集合进行排序(先依据public 构造方法优先参数数量降序排序,然后非public构造方法 参数降序排序),这样可以提高构造方法的查找速率.根据构造参数转换对应的参数类型
构造参数不正确性验证
根据实例化策略以及得到的构造参数以及构造函数实例化bean.
instantiateBean
1 | //AbstractAutowireCapableBeanFactory |
2 | //使用默认构造参数初始化bean |
3 | protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) { |
4 | try { |
5 | Object beanInstance; |
6 | final BeanFactory parent = this; |
7 | if (System.getSecurityManager() != null) { |
8 | beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () -> |
9 | //实例化策略 |
10 | getInstantiationStrategy().instantiate(mbd, beanName, parent), |
11 | getAccessControlContext()); |
12 | } |
13 | else { |
14 | beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent); |
15 | } |
16 | BeanWrapper bw = new BeanWrapperImpl(beanInstance); |
17 | initBeanWrapper(bw); |
18 | return bw; |
19 | } |
20 | catch (Throwable ex) { |
21 | throw new BeanCreationException( |
22 | mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex); |
23 | } |
24 | } |
实例化策略 SimpleInstantiationStrategy
在实例化过程中反复用到了实例化策略 ,具体是什么呢? 通过前面的分析,我们完全可以通过反射来构造实例对象。但是是spring并没有采取反射的方式。而是采用了另外一种方式
1 | public class SimpleInstantiationStrategy{ |
2 | |
3 | public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) { |
4 | //如果有需要覆盖或者动态替换的方法,则需要使用CGLB进行动态代理。因为可以在创建的过程中,将动态方法织入类中。 |
5 | //但是,如果没有动态改变的方法,则直接使用反射就可以了 |
6 | // Don't override the class with CGLIB if no overrides. |
7 | if (!bd.hasMethodOverrides()) { |
8 | Constructor<?> constructorToUse; |
9 | synchronized (bd.constructorArgumentLock) { |
10 | constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod; |
11 | if (constructorToUse == null) { |
12 | final Class<?> clazz = bd.getBeanClass(); |
13 | if (clazz.isInterface()) { |
14 | throw new BeanInstantiationException(clazz, "Specified class is an interface"); |
15 | } |
16 | try { |
17 | if (System.getSecurityManager() != null) { |
18 | constructorToUse = AccessController.doPrivileged( |
19 | (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor); |
20 | } |
21 | else { |
22 | constructorToUse = clazz.getDeclaredConstructor(); |
23 | } |
24 | bd.resolvedConstructorOrFactoryMethod = constructorToUse; |
25 | } |
26 | catch (Throwable ex) { |
27 | throw new BeanInstantiationException(clazz, "No default constructor found", ex); |
28 | } |
29 | } |
30 | } |
31 | return BeanUtils.instantiateClass(constructorToUse); |
32 | } |
33 | else { |
34 | // Must generate CGLIB subclass. |
35 | return instantiateWithMethodInjection(bd, beanName, owner); |
36 | } |
37 | } |
38 | } |
39 | // 使用CGLB |
40 | public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationStrategy { |
41 | |
42 | protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) { |
43 | return instantiateWithMethodInjection(bd, beanName, owner, null); |
44 | } |
45 | |
46 | protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner, |
47 | @Nullable Constructor<?> ctor, Object... args) { |
48 | // Must generate CGLIB subclass... |
49 | return new CglibSubclassCreator(bd, owner).instantiate(ctor, args); |
50 | } |
51 | } |
52 | ` |
记录创建bean 的ObjectFactory
在doCreateBean 方法中有如下代码片段:
1 | protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) |
2 | throws BeanCreationException { |
3 | ... |
4 | ... |
5 | //earlySingletonExposure 字面意思是提早暴露单例 |
6 | boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && |
7 | isSingletonCurrentlyInCreation(beanName)); |
8 | if (earlySingletonExposure) { |
9 | if (logger.isTraceEnabled()) { |
10 | logger.trace("Eagerly caching bean '" + beanName + |
11 | "' to allow for resolving potential circular references"); |
12 | } |
13 | //为避免后期循环依赖,可以在bean初始化完前,将创建实例的ObjectFactory加入工厂 |
14 | addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); |
15 | } |
16 | // Initialize the bean instance. |
17 | Object exposedObject = bean; |
18 | try { |
19 | //填充bean属性 |
20 | populateBean(beanName, mbd, instanceWrapper); |
21 | exposedObject = initializeBean(beanName, exposedObject, mbd); |
22 | } |
23 | } |
24 | //AbstractAutowireCapableBeanFactory.getEarlyBeanReference |
25 | //对bean的再次依赖引用,主要是引用 SmartInstantiationAwareBeanPostProcessor |
26 | //其中我们熟知的AOP就是在这里将advice动态织入bean中。 |
27 | protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { |
28 | Object exposedObject = bean; |
29 | if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { |
30 | for (BeanPostProcessor bp : getBeanPostProcessors()) { |
31 | if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { |
32 | SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; |
33 | exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName); |
34 | } |
35 | } |
36 | } |
37 | return exposedObject; |
38 | } |
- earlySingletonExposure 字面意思是提早暴露单例
- mbd.isSingleton() RootBeanDefinition是否代表的是单例
- this.allowCircularReferences 是否允许循环依赖
- isSingletonCurrentlyInCreation(beanName) 该bean是否在创建中
以简单的AB 循环依赖为例, 类A 中含有属性类B ,而类B 中又会含有属性类A,那么初始化beanA 的过程
spring处理循环依赖的办法。在B中创建依赖A时通过ObjectFactory提供的实例化方法来中断A中属性填充。使B中持有的A仅仅是刚刚初始化并没有填充任何属性的A,而真正初始化A的步骤还是在最开始创建A的的时候进行的,但是因为A与B中的A所表示属性地址是一样的,所以在A中创建好的属性自然可以通过B中的A获取,这样就解决了循环依赖的问题。
属性注入(populateBean)
1 | protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { |
2 | if (bw == null) { |
3 | if (mbd.hasPropertyValues()) { |
4 | throw new BeanCreationException( |
5 | mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); |
6 | } |
7 | else { |
8 | // Skip property population phase for null instance. |
9 | return; |
10 | } |
11 | } |
12 | // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the |
13 | // state of the bean before properties are set. This can be used, for example, |
14 | // to support styles of field injection. |
15 | if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { |
16 | for (BeanPostProcessor bp : getBeanPostProcessors()) { |
17 | if (bp instanceof InstantiationAwareBeanPostProcessor) { |
18 | InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; |
19 | // 返回值是否填充bean |
20 | if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { |
21 | return; |
22 | } |
23 | } |
24 | } |
25 | } |
26 | //获取属性值 |
27 | PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); |
28 | int resolvedAutowireMode = mbd.getResolvedAutowireMode(); |
29 | if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { |
30 | MutablePropertyValues newPvs = new MutablePropertyValues(pvs); |
31 | // Add property values based on autowire by name if applicable. |
32 | if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { |
33 | // 依据名称注入 |
34 | autowireByName(beanName, mbd, bw, newPvs); |
35 | } |
36 | // Add property values based on autowire by type if applicable. |
37 | if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { |
38 | // 依据类型注入 |
39 | autowireByType(beanName, mbd, bw, newPvs); |
40 | } |
41 | pvs = newPvs; |
42 | } |
43 | //判断后处理器是否已经初始化完成 |
44 | boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); |
45 | //是否对依赖进行检查 |
46 | boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); |
47 | PropertyDescriptor[] filteredPds = null; |
48 | if (hasInstAwareBpps) { |
49 | if (pvs == null) { |
50 | pvs = mbd.getPropertyValues(); |
51 | } |
52 | for (BeanPostProcessor bp : getBeanPostProcessors()) { |
53 | if (bp instanceof InstantiationAwareBeanPostProcessor) { |
54 | InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; |
55 | PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); |
56 | if (pvsToUse == null) { |
57 | if (filteredPds == null) { |
58 | filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); |
59 | } |
60 | pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); |
61 | if (pvsToUse == null) { |
62 | return; |
63 | } |
64 | } |
65 | pvs = pvsToUse; |
66 | } |
67 | } |
68 | } |
69 | if (needsDepCheck) { |
70 | if (filteredPds == null) { |
71 | filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); |
72 | } |
73 | checkDependencies(beanName, mbd, filteredPds, pvs); |
74 | } |
75 | |
76 | if (pvs != null) { |
77 | applyPropertyValues(beanName, mbd, bw, pvs); |
78 | } |
79 | } |
autowireByName
依据注入类型(byName/byType)提取依赖的bean,并统一存入PropertyValues中,首先看一下byName 注入:
1 | protected void autowireByName( |
2 | String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { |
3 | // 寻找需要依赖注入的非简单属性 |
4 | String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); |
5 | for (String propertyName : propertyNames) { |
6 | if (containsBean(propertyName)) { |
7 | //初始化相关的bean |
8 | Object bean = getBean(propertyName); |
9 | pvs.add(propertyName, bean); |
10 | //注册依赖关系 |
11 | registerDependentBean(propertyName, beanName); |
12 | if (logger.isTraceEnabled()) { |
13 | logger.trace("Added autowiring by name from bean name '" + beanName + |
14 | "' via property '" + propertyName + "' to bean named '" + propertyName + "'"); |
15 | } |
16 | } |
17 | else { |
18 | if (logger.isTraceEnabled()) { |
19 | logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName + |
20 | "' by name: no matching bean found"); |
21 | } |
22 | } |
23 | } |
24 | } |
autowireBypeType
1 | protected void autowireByType( |
2 | String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { |
3 | TypeConverter converter = getCustomTypeConverter(); |
4 | if (converter == null) { |
5 | converter = bw; |
6 | } |
7 | Set<String> autowiredBeanNames = new LinkedHashSet<>(4); |
8 | //寻找bw 中需要依赖注入的属性 |
9 | String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); |
10 | for (String propertyName : propertyNames) { |
11 | try { |
12 | PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); |
13 | // Don't try autowiring by type for type Object: never makes sense, |
14 | // even if it technically is a unsatisfied, non-simple property. |
15 | if (Object.class != pd.getPropertyType()) { |
16 | //寻找指定属性的set 方法 |
17 | MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); |
18 | // Do not allow eager init for type matching in case of a prioritized post-processor. |
19 | boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered); |
20 | DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); |
21 | //解析指定beanName 属性匹配的值,并把解析到的属性名称存储到autowiredBeanNames 中,当属性存在多个封装bean时,如: |
22 | //@Autowired private List<A> aList; 将会将找到所有匹配A类型的bean 并将其注入 |
23 | Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); |
24 | if (autowiredArgument != null) { |
25 | pvs.add(propertyName, autowiredArgument); |
26 | } |
27 | for (String autowiredBeanName : autowiredBeanNames) { |
28 | //注册依赖 |
29 | registerDependentBean(autowiredBeanName, beanName); |
30 | if (logger.isTraceEnabled()) { |
31 | logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" + |
32 | propertyName + "' to bean named '" + autowiredBeanName + "'"); |
33 | } |
34 | } |
35 | autowiredBeanNames.clear(); |
36 | } |
37 | } |
38 | catch (BeansException ex) { |
39 | throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex); |
40 | } |
41 | } |
42 | } |
resolveDependency 寻找匹配的类型
1 | //DefaultListableBeanFactory |
2 | public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName, |
3 | @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { |
4 | descriptor.initParameterNameDiscovery(getParameterNameDiscoverer()); |
5 | if (Optional.class == descriptor.getDependencyType()) { |
6 | //optional 函数类型的解析(描述符类型) |
7 | return createOptionalDependency(descriptor, requestingBeanName); |
8 | } |
9 | else if (ObjectFactory.class == descriptor.getDependencyType() || |
10 | ObjectProvider.class == descriptor.getDependencyType()) { |
11 | // ObjectFactory 或者ObjectFactory 提供者类型的 |
12 | return new DependencyObjectProvider(descriptor, requestingBeanName); |
13 | } |
14 | else if (javaxInjectProviderClass == descriptor.getDependencyType()) { |
15 | //javaxInjectProviderClass 类型的注解 |
16 | return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName); |
17 | } |
18 | else { |
19 | //通用逻辑处理 |
20 | Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary( |
21 | descriptor, requestingBeanName); |
22 | if (result == null) { |
23 | result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); |
24 | } |
25 | return result; |
26 | } |
27 | } |
28 | |
29 | public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, |
30 | @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { |
31 | //封装注入点 |
32 | InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor); |
33 | try { |
34 | //空方法,提供给子类实现,提供了在解析dependceny 之前利用FactoryBean预处理的一个入口, |
35 | Object shortcut = descriptor.resolveShortcut(this); |
36 | if (shortcut != null) { |
37 | return shortcut; |
38 | } |
39 | Class<?> type = descriptor.getDependencyType(); |
40 | //spring 支持@value类型的注解 |
41 | Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); |
42 | if (value != null) { |
43 | if (value instanceof String) { |
44 | String strVal = resolveEmbeddedValue((String) value); |
45 | BeanDefinition bd = (beanName != null && containsBean(beanName) ? |
46 | getMergedBeanDefinition(beanName) : null); |
47 | value = evaluateBeanDefinitionString(strVal, bd); |
48 | } |
49 | TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); |
50 | try { |
51 | return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor()); |
52 | } |
53 | catch (UnsupportedOperationException ex) { |
54 | // A custom TypeConverter which does not support TypeDescriptor resolution... |
55 | return (descriptor.getField() != null ? |
56 | converter.convertIfNecessary(value, type, descriptor.getField()) : |
57 | converter.convertIfNecessary(value, type, descriptor.getMethodParameter())); |
58 | } |
59 | } |
60 | //解析其他各种类型的情况: |
61 | //descriptor 是StreamDependencyDescriptor类型 |
62 | //list |
63 | //collection |
64 | //Map 类型 |
65 | Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); |
66 | if (multipleBeans != null) { |
67 | return multipleBeans; |
68 | } |
69 | // 获取指定到的候选bean |
70 | Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); |
71 | if (matchingBeans.isEmpty()) { |
72 | if (isRequired(descriptor)) { |
73 | raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); |
74 | } |
75 | return null; |
76 | } |
77 | |
78 | String autowiredBeanName; |
79 | Object instanceCandidate; |
80 | if (matchingBeans.size() > 1) { |
81 | //确定多个候选bean中的一个 |
82 | autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor); |
83 | if (autowiredBeanName == null) { |
84 | if (isRequired(descriptor) || !indicatesMultipleBeans(type)) { |
85 | return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans); |
86 | } |
87 | else { |
88 | // In case of an optional Collection/Map, silently ignore a non-unique case: |
89 | // possibly it was meant to be an empty collection of multiple regular beans |
90 | // (before 4.3 in particular when we didn't even look for collection beans). |
91 | return null; |
92 | } |
93 | } |
94 | instanceCandidate = matchingBeans.get(autowiredBeanName); |
95 | } |
96 | else { |
97 | // We have exactly one match. |
98 | Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next(); |
99 | autowiredBeanName = entry.getKey(); |
100 | instanceCandidate = entry.getValue(); |
101 | } |
102 | |
103 | if (autowiredBeanNames != null) { |
104 | autowiredBeanNames.add(autowiredBeanName); |
105 | } |
106 | if (instanceCandidate instanceof Class) { |
107 | instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this); |
108 | } |
109 | Object result = instanceCandidate; |
110 | if (result instanceof NullBean) { |
111 | if (isRequired(descriptor)) { |
112 | raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); |
113 | } |
114 | result = null; |
115 | } |
116 | if (!ClassUtils.isAssignableValue(type, result)) { |
117 | throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass()); |
118 | } |
119 | return result; |
120 | } |
121 | finally { |
122 | ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint); |
123 | } |
124 | } |
初始化bean (initializeBean)
xml中的init-method属性,这个属性的作用是在bean实例化之前,调用 init-method指定的方法来根据用户业务进行相应的实例化。改方法的执行就是在属性填充完成后执行。
1 | protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { |
2 | if (System.getSecurityManager() != null) { |
3 | AccessController.doPrivileged((PrivilegedAction<Object>) () -> { |
4 | invokeAwareMethods(beanName, bean); |
5 | return null; |
6 | }, getAccessControlContext()); |
7 | } |
8 | else { |
9 | //对特殊bean的处理:Aware,BeanClassLoaderAware,BeanFactoryAware |
10 | invokeAwareMethods(beanName, bean); |
11 | } |
12 | Object wrappedBean = bean; |
13 | if (mbd == null || !mbd.isSynthetic()) { |
14 | //应用处理器 |
15 | wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); |
16 | } |
17 | try { |
18 | //激活自定义的init方法 |
19 | invokeInitMethods(beanName, wrappedBean, mbd); |
20 | } |
21 | catch (Throwable ex) { |
22 | throw new BeanCreationException( |
23 | (mbd != null ? mbd.getResourceDescription() : null), |
24 | beanName, "Invocation of init method failed", ex); |
25 | } |
26 | if (mbd == null || !mbd.isSynthetic()) { |
27 | //后处理器 |
28 | wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); |
29 | } |
30 | return wrappedBean; |
31 | } |
- 激活 Aware 方法
Spring 中提供的一些 Aware 的接口:
- BeanFactoryAware: 在bean 初始化之后,会注入BeanFactory 的实例。
- ApplicationContextAware: 在bean 初始化之后,会注入ApplicationContext 的实例。
- ResourceLoaderAware
- ServletContextAware
- 处理器的应用
BeanProcessor 相信大家都不陌生。这是spring开放架构中的一个必不可少的亮点。给用户充足的权限去更改或者拓展Spring。除了BeanPostProcessor外,还有其他的PostProcessor。当然大部分都是以次为基础的,继承自BeanPostProcessor。BeanPostProcessor的使用卫视是在客户自定义初始化方法前以及调用自定义初始化方法后,会分别调用BeanPostProcessor 的postProcessorBeforeInitialization 和postProcessorAfterInitialization方法,使用户可以根据自己的业务需求进行相应处理。
1 | // before 方法 |
2 |
|
3 | public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) |
4 | throws BeansException { |
5 | |
6 | Object result = existingBean; |
7 | for (BeanPostProcessor processor : getBeanPostProcessors()) { |
8 | Object current = processor.postProcessBeforeInitialization(result, beanName); |
9 | if (current == null) { |
10 | return result; |
11 | } |
12 | result = current; |
13 | } |
14 | return result; |
15 | } |
16 | // after 方法 |
17 |
|
18 | public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) |
19 | throws BeansException { |
20 | |
21 | Object result = existingBean; |
22 | for (BeanPostProcessor processor : getBeanPostProcessors()) { |
23 | Object current = processor.postProcessAfterInitialization(result, beanName); |
24 | if (current == null) { |
25 | return result; |
26 | } |
27 | result = current; |
28 | } |
29 | return result; |
30 | } |
- 激活自定义的方法
客户定制的初始化方法除了我们熟知的使用
init-method
外,还有使自定义的bean实现 initializingBean 接口。并在 afterPropertiesSet 中实现自己定义的业务逻辑。
init-method 与afterPropertiesSet 都是初始化bean时执行。执行顺序是 afterPropertiesSet 先执行,init-method 后执行。
1 | rotected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd) |
2 | throws Throwable { |
3 | // 检查是否是InitializingBean,是的话先执行 afterPropertiesSet 方法 |
4 | boolean isInitializingBean = (bean instanceof InitializingBean); |
5 | if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { |
6 | if (logger.isTraceEnabled()) { |
7 | logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); |
8 | } |
9 | if (System.getSecurityManager() != null) { |
10 | try { |
11 | AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> { |
12 | ((InitializingBean) bean).afterPropertiesSet(); |
13 | return null; |
14 | }, getAccessControlContext()); |
15 | } |
16 | catch (PrivilegedActionException pae) { |
17 | throw pae.getException(); |
18 | } |
19 | } |
20 | else { |
21 | ((InitializingBean) bean).afterPropertiesSet(); |
22 | } |
23 | } |
24 | // init-method 调用 |
25 | if (mbd != null && bean.getClass() != NullBean.class) { |
26 | String initMethodName = mbd.getInitMethodName(); |
27 | if (StringUtils.hasLength(initMethodName) && |
28 | !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && |
29 | !mbd.isExternallyManagedInitMethod(initMethodName)) { |
30 | //用户自定义的init-meethod |
31 | invokeCustomInitMethod(beanName, bean, mbd); |
32 | } |
33 | } |
34 | } |
注册DisposableBean
spring 不但提供了对初始化方法的拓展入口,同样也提供了销毁方法的入口。对于销毁方法的拓展,除了我们熟知的destroy-method外,用户还可以注册后处理器 DestructionAwareBeanPostProcessors来统一bean 的销毁方法。
1 | protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) { |
2 | AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null); |
3 | if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) { |
4 | if (mbd.isSingleton()) { |
5 | // Register a DisposableBean implementation that performs all destruction |
6 | // work for the given bean: DestructionAwareBeanPostProcessors, |
7 | // DisposableBean interface, custom destroy method. |
8 | // 单例模式下注册要销毁的bean,此方法中会处理实现DisposableBean的bean, |
9 | // 并且对所有的bean使用DestructionAwareBeanPostProcessors 处理 |
10 | registerDisposableBean(beanName, |
11 | new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); |
12 | } |
13 | else { |
14 | // 自定义scope 处理 |
15 | // A bean with a custom scope... |
16 | Scope scope = this.scopes.get(mbd.getScope()); |
17 | if (scope == null) { |
18 | throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'"); |
19 | } |
20 | scope.registerDestructionCallback(beanName, |
21 | new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); |
22 | } |
23 | } |
24 | } |
总结
bean 的创建经历了三大步。第一步:bean 的加载; 第二步: 准备创建bean; 第三步: bean 的创建。
bean 的加载:
- 转换对应的beanName
- 尝试从缓存中加载单例
- bean 的实例化
- 原型模式的依赖检查
- 检查parentBeanFactory
- 将存储xml 配置文件的GerenicBeanDefinition 转换为 RootBeanDefinition
- 寻找依赖 -> spring 在加载bean的时候,会优先加载该bean 所依赖的bean
- 针对不同的scope进行bean的创建
- 类型转换
准备创建bean
- 根据设置的class属性及className来解析class
- 对override属性进行标记及验证
处理spring中的lookup-method 和replaced-method的。这两个配置的加载其实就是将配置统一存在BeanDefinition中的methodOverrides属性里。此处的处理,就是对methodOverrides的处理。 - 应用初始化前的后处理器,解析指定bean是否存在初始化前的短路操作。
创建bean
- 如果是单例则需要首先清除缓存。
- 实例化bean ,将BeanDefinition 转换为BeanWrapper 。转换是一个复杂的过程,但是我们可以尝试概括大致的功能,如下所示。
- 如果存在工厂方法则使用工厂方法进行初始化。
- 一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造函数并进行初始化。
- 如果既不存在工厂方法也不存在带有参数的构造函数,则使用默认的构造函数进行bean 的实例f匕。
- MergedBeanDefinitionPostProcessor 的应用。
- bean 合并后的处理, Autowired 注解正是通过此方法实现诸如类型的预解析。
- 依赖处理。
- 在Spring 中会有循环依赖的情况,例如,当A 中含有B 的属性,而B 中又含有A 的属性时就会构成一个循环依赖,此时如果A 和B 都是单例,那么在Spring 中的处理方式就是当创建B 的时候,涉及自动注入A 的步骤时,并不是直接去再次创建A ,而是通过放入缓存中的ObjectFactory 来创建实例,这样就解决了循环依赖的问题。
- 属性填充。将所有属性填充至bean 的实例中。
- 循环依赖检查。
- 之前有提到过,在Spring 中解决循环依赖只对单例有效,而对于prototype 的bean, Spring
没有好的解决办法,唯一要做的就是抛出异常。在这个步骤里面会检测已经加载的bean 是否已经出现了依赖循环,并判断是否需要抛出异常。
- 之前有提到过,在Spring 中解决循环依赖只对单例有效,而对于prototype 的bean, Spring
- 注册DisposableBean 。
- 如果配置了destroy-method ,这里需要注册以便于在销毁时候调用。
- 完成创建井返回。
- 可以看到上面的步骤非常的繁琐,每一步骤都使用了大量的代码来完成其功能,最复杂也是最难以理解的当属循环依赖的处理,在真正进入doCreateBean 前我们有必要先了解下循环依赖。