Spring源码:Bean创建(一)

本文详细解析了Spring中Bean的创建过程,从BeanFactory.getBean()开始,包括从缓存中获取单例、实例化Bean、处理依赖检查、类型转换等步骤。特别地,对于FactoryBean的情况进行了详细阐述,解释了如何从bean实例中获取对象,并介绍了防止循环依赖的策略。
摘要由CSDN通过智能技术生成

1、BeanFactory.getBean(String name)方法

//AbstractBeanFactory.java

public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

2、真正创建Bean的地方--doCreateBean()

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
		//提取对应的beanName,比如去掉FactoryBean的前缀“&”
		final String beanName = transformedBeanName(name);
		Object bean;

		/*
		在创建单例bean的时候会存在依赖注入的情况,为了避免循环依赖
		Spring在创建bean的时候,是不能bean创建完成就会将创建bean的ObjectFactory提早曝光
		*/
		// 尝试从缓存中获取或者singletonFactories中的objectFactort获取
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			//返回bean的实例。如果不是FactoryBean则直接返回,否则会调用getObject返回bean,并且将bean放入factoryBean对应的缓存中
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}
		else {
			// 检测是否有循环依赖
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// 如果当前的beanFactory不包含该bean,就从parentBeanFactory中查找、创建
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				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 {
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
			}
			// --------------------------------------------------------------------
			
			//如果不仅仅是做类型检测,而是需要创建bean,则需要记录该bean被创建
			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}

			try {
				//将xml配置文件的GernericBeanDefinition转换为RootBeanDefinition。如果需要创建的bean有父bean的话,还会合并父bean的属性
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				//验证isAbstract属性,如果bean定义为abstract则会抛出异常
				checkMergedBeanDefinition(mbd, beanName, args);

				// 如果存在依赖,则递归实例化依赖的bean
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						if (isDep
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值