spring学习(四)——Bean的加载(scope 的 Bean 创建)

参考文章:

http://www.iocoder.cn

 

根据之前的代码bean类的创建被分为三种方式

  • singleton :mbd.isSingleton()
  • prototype:mbd.isPrototype()
  • 其他

singleton

其逻辑代码为

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.
			// 显式从单例缓存中删除 Bean 实例
			// 因为单例模式下为了解决循环依赖,可能他已经存在了,所以销毁它。
			destroySingleton(beanName);
			throw ex;
		}
	});
	//从 bean 实例中获取对象
	bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

其方法getSingleton的详细逻辑

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "Bean name must not be null");
		// 加锁singletonObjects
		synchronized (this.singletonObjects) {
			// 从singletonObjects中获得bean,因为 singleton 模式其实就是复用已经创建的 bean 所以这步骤必须检查
			Object singletonObject = this.singletonObjects.get(beanName);
			// 假如不存
			if (singletonObject == null) {
				if (this.singletonsCurrentlyInDestruction) {
					throw new BeanCreationNotAllowedException(beanName,
							"Singleton bean creation not allowed while singletons of this factory are in destruction " +
							"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
				}
				// Singleton创建的前置
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					//初始化bean
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
					// Has the singleton object implicitly appeared in the meantime ->
					// if yes, proceed with it since the exception indicates that state.
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						throw ex;
					}
				}
				catch (BeanCreationException ex) {
					if (recordSuppressedExceptions) {
						for (Exception suppressedException : this.suppressedExceptions) {
							ex.addRelatedCause(suppressedException);
						}
					}
					throw ex;
				}
				finally {
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}
					// 后置处理
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
					// Singleton加入缓存
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}

代码的后部分 addSingleton中将相关beanName在map中进行放入和移除的逻辑

prototype

其逻辑代码为

// 原型模式
else if (mbd.isPrototype()) {
	// It's a prototype -> create a new instance.
	Object prototypeInstance = null;
	try {
		// 前置处理
		beforePrototypeCreation(beanName);
		// 创建bean
		prototypeInstance = createBean(beanName, mbd, args);
	}
	finally {
		//后置处理
		afterPrototypeCreation(beanName);
	}
	//从 bean 实例中获取对象
	bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}

其他

其逻辑代码为

else {
	// 获得 scopeName 对应的 Scope 对象
	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 {
		// 从指定的 scope 下创建 bean
		Object scopedInstance = scope.get(beanName, () -> {
			beforePrototypeCreation(beanName);
			try {
				// 创建 Bean 对象
				return createBean(beanName, mbd, args);
			}
			finally {
				afterPrototypeCreation(beanName);
			}
		});
		// 从 Bean 实例中获取对象
		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);
	}
}

这三个逻辑判断的核心方法为:

  • createBean(beanName, mbd, args);
  • getObjectForBeanInstance(scopedInstance, name, beanName, mbd);

getObjectForBeanInstance的核心方法逻辑可以查看从缓存获取单例 Bean

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大·风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值