栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

资深小白谈spring(十八):getBean

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

资深小白谈spring(十八):getBean

资深小白谈spring(十八):getBean

1、preInstantiateSingletons这个方法会遍历beanNames时首先判断这个bean是不是FactoryBean,如果是则创建FactoryBean,否则直接getBean创建这个bean。这个方法在容器初始化的时候被调用,至于单例的非懒加载的bean才会被创建。

2、getBean调用了doGetBean方法,看了这么久的spring代码,想必你已经指定带do的方法才是真正干活的。(doGetBean方法稍长,将拆分成几段)

3、doGetBean方法一进来就从三级缓存中取,这个三级缓存是用来解决spring的循环依赖的,后面的章节会详细讲解。由于一开始这个bean是没有创建,所有肯定获取不到,所有第一个if条件是不成立。
4、if条件不成立就会进入else,这一段代码就是看这个容器有没有父容器,如果有则调用父容器的getBean方法创建Bean。举个例子,例如项目中引用了spring和springMVC的web容器,SpringMVC就是子容器,spring就是父容器。这个在将springMVC的时候细讲。
5、如果没有父容器,就用这个容器创建bean。创建时先检查这个bean有没有dependsOn属性,如果有则优先创建dependsOn指定的bean。
6、检查完dependsOn就判断这个bean的作用域,这里的作用域有三种:单例、多例以及自定义的作用域。不同的作用域创建bean的流程是不一样的,所有后面会分开细讲。

				// 单例域
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
				//多例域
				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}
				//自定义作用域
				else {
					String scopeName = mbd.getScope();
					final Scope scope = this.scopes.get(scopeName);
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
						Object scopedInstance = scope.get(beanName, () -> {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						});
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new BeanCreationException(beanName,
								"Scope '" + scopeName + "' is not active for the current thread; consider " +
								"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
								ex);
					}
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

7、结语:本节主要展示了doGetBean方法主要干的事情,下一节将围绕单例域展开spring循环依赖的讲解。

  • 上一篇:资深小白谈spring(十七):BeanDefinition的合并原理
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/275418.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号