我是靠谱客的博主 帅气硬币,这篇文章主要介绍SpringBoot源码学习(十一) - bean的实例化过程,现在分享给大家,希望可以做个参考。

上一篇文章中我们解释了Spring对于类级别的注解的解析过程,通过类级别的注解spring基本是将所有该加载的类都加载到待解析的BeanDefineMap中去了。但是BeanDefineMap可不是实例化的bean哦,可以说通过类级别的注解之后Spring还是一个粗糙的商品,但是要变成一个精美的可以使用的Bean还需要将这个粗糙的商品进行一番美化。那么这个美化的动作就是content.getBean()方法了。考虑到类的实例化过程可能会依赖其他的bean还有一些类内部的注解比如@Autowired、@Queries等都需要考虑。所以说getBean是比较复杂的。之前通过源码查看的时候稍微看到了这块,感到压力很大。但是有时候确实让人迫不得已的要去做这件事。因为我们还没有解释@Autowired是如何注入的问题。所以就让我们通过这期的学习解答这个问题吧!

在之前我们说上述代码就是实例化bean的代码。这块我们主要看一下

beanFactory.preInstantiateSingletons();方法

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
@Override public void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) { logger.trace("Pre-instantiating singletons in " + this);     } //拿到所有注册的bean的名称     List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); //遍历 for (String beanName : beanNames) {     //拿到粗糙的bean RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { //判断是否为工厂bean if (isFactoryBean(beanName)) {         //给beanName+前缀 & 符号 Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) {           //如果是工厂bean final FactoryBean<?> factory = (FactoryBean<?>) bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); }             //调用正在的getBean if (isEagerInit) { getBean(beanName); } } } else {         //非工厂bean getBean(beanName); } } }     // 通过上述方法就将bean注册进去了。这里迭代做一些处理 for (String beanName : beanNames) {     //拿到单例bean Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) {         //判断当前的bean是否实现了SmartInitializingSingleton接口 final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else {         //做一些后置处理 smartSingleton.afterSingletonsInstantiated(); } } }   }

通过上边的分析,我们知道getBean是很重要的方法。那么这块做了哪些工作?

我们看到这里的doGetBean方法,说明这里是正真搞事情的地方。毫无疑问,伟大的目标必将付出艰苦的努力。这块的代码很长!

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { //先把传入的名称进行转化。因为可能传入的是别名什么的,所以要处理一下,如果之前都添加了前缀 final String beanName = transformedBeanName(name);     Object bean;     // 先尝试从缓存中加载bean,如果不存在会调用getBean方法,因为创建单例bean的时候存在循环依赖的问题     //Spring创建bean的时候是不等bean创建结束就将bean的ObjectFactory提早曝光。就是将ObjectFactory加入到缓存。     //一旦下一个bean创建的时候需要依赖上一个bean的时候则可以直接使用     //从缓存或者singleFactories中的ObjectFactory中获取。 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); } } /** * 如果sharedInstance是普通的单例bean,下面的方法会直接返回。但如果 * sharedInstance是FactoryBean类型的,则需调用getObject工厂方法获取真正的 * bean实例。如果用户想获取 FactoryBean 本身,这里也不会做特别的处理,直接返回 * 即可。毕竟 FactoryBean 的实现类本身也是一种 bean,只不过具有一点特殊的功能而已。 */      //有时候BeanFactory返回的并不是实例本身而是指定方法返回的实例 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);     } else { //Spring只能解决单例对象的setter注入的循环依赖,不能解决构造器注入, //也不能解决多实例的循环依赖 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName);       } //如果已经加载的类没有当前类就从parentBeanFactory中加载。 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {    //若存在父工厂,切当前的bean工厂不存在当前的bean定义,    //那么bean定义是存在于父beanFactory中    //获取原始名称 String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) {           //委托给构造函数 return (T) parentBeanFactory.getBean(nameToLookup, args); } else if (requiredType != null) { // 没有args,委托给标准的getBean()处理 return parentBeanFactory.getBean(nameToLookup, requiredType); } else {         //使用父工厂创建bean return (T) parentBeanFactory.getBean(nameToLookup); } } /** * 方法参数typeCheckOnly ,是用来判断调用getBean(...) 方法时,表示是否为仅仅进行类型检查获取Bean对象 * 如果不是仅仅做类型检查,而是创建Bean对象,则需要调用markBeanAsCreated(String beanName) 方法,进行记录 */ if (!typeCheckOnly) { markBeanAsCreated(beanName);       } try { //从容器中获取beanName相应的GenericBeanDefinition对象,并将其转换为RootBeanDefinition对象 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); //检查当前创建的bean定义是不是抽象的bean定义 checkMergedBeanDefinition(mbd, beanName, args);       //处理dependsOn的依赖(这个不是我们所谓的循环依赖 而是bean创建前后的依赖)        //依赖bean的名称 String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { //beanName是当前正在创建的bean,dep是正在创建的bean的依赖的bean的名称 if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } //保存的是依赖beanName之间的映射关系: //依赖beanName -> beanName的集合 registerDependentBean(dep, beanName); try { //获取dependsOn的bean getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } //是单例则创建单例Bean if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try {             //这里是重点 return createBean(beanName, mbd, args); } catch (BeansException ex) {              //清除旧信息 destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) {           // 如果是一个属性,就创建 Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else {         //指定scope上实例化bean String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, () -> { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); } } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; }     }     //一些检测 if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return convertedBean; } catch (TypeMismatchException ex) { if (logger.isTraceEnabled()) { logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; }

通过上述代码查看,我们大概描述一下getBean的过程,首先对bean的名称做一些处理,之前的bean名称都是添加工厂名称的。所以要处理一下。处理完之后先从缓存中获取bean,同时将该bean对应的ObjectFactory加入到缓存中,同时如果从缓存中获取到之后就进行对Bean进行判断,看是否为工厂Bean,如果是工厂bean就需要返回对应方法的返回结果。判断完毕之后就对bean的属性进行初始化了,如果是单例就处理单例,如果是property就相应做处理。当然还有对scope做处理的。我们一般都是单例吧。当然如果没有从工厂中获取到bean的话就尝试从父工厂中获取。

那么我们看一下createBean方法都做了哪些事情

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)       throws BeanCreationException { if (logger.isTraceEnabled()) { logger.trace("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; //解析class Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass);     } // 验证以及准备覆盖方法 try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex);     } try {       // 给BeanPostProcessors一个机会来替换原来的bean       //该方法里有两个接口可以对bean进行处理       //instantiationAwareBeanPostProcessor Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { //返回 return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex);     } try {     //如果BeanPostProcessors没有做处理就自己创建 Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }     catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
//这里才是真正创建bean的地方 protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) {         //从缓存中移除 instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);         } if (instanceWrapper == null) {         //创建 instanceWrapper = this.createBeanInstance(beanName, mbd, args);         } Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } //这里处理类内注解,通过查看我们发现主要有图所示的处理类。这些类是爱注册beanpostprocessors中加入的 synchronized(mbd.postProcessingLock) { if (!mbd.postProcessed) { try { //处理的过程 this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable var17) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);                 } mbd.postProcessed = true; }         }         //是否提前曝光 boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName); if (earlySingletonExposure) { if (this.logger.isTraceEnabled()) { this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");             } this.addSingletonFactory(beanName, () -> { return this.getEarlyBeanReference(beanName, mbd, bean); });         }         Object exposedObject = bean; try {         //对bean进行填充 this.populateBean(beanName, mbd, instanceWrapper);             //这块是实例化bean调用后置处理器的部分exposedObject就是bean实体 exposedObject = this.initializeBean(beanName, exposedObject, mbd); } catch (Throwable var18) { if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) { throw (BeanCreationException)var18;             } throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);         } if (earlySingletonExposure) { Object earlySingletonReference = this.getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) { String[] dependentBeans = this.getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length); String[] var12 = dependentBeans;                     int var13 = dependentBeans.length; for(int var14 = 0; var14 < var13; ++var14) { String dependentBean = var12[var14]; if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); }                     } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } }         } try { this.registerDisposableBeanIfNecessary(beanName, bean, mbd); return exposedObject; } catch (BeanDefinitionValidationException var16) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16); }     }

        大概看源码发现doCreateBean才是主要的创建Bean的地方,主要的操作就是对类内部注解进行解析,然后解析完毕之后会统一调initializeBean方法。initalizeBean就开始执行Aware、前置处理器、初始化方法、后置处理器等顺序进行执行,通过这些方法后类才真正的实例化并注册到IOC中。至于initalizeBean没有什么可说的,都是常规操作。但是我们需要记住的是它调用的过程,首先是一波Aware接口的调用,之后是BeanPostProfrosses的前置处理器,然后是Bean的初始化方法,最后是BeanPostProcessors的后置处理方法。而且这个InitalizeBean的方法是只要调用了getBean都会执行。所有保证了InitalizeBean里边的方法都可以执行到到。

最后

以上就是帅气硬币最近收集整理的关于SpringBoot源码学习(十一) - bean的实例化过程的全部内容,更多相关SpringBoot源码学习(十一)内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(53)

评论列表共有 0 条评论

立即
投稿
返回
顶部