Spring5 IOC源码解读系列12—getBean方法

一 概述

getBean方法从缓存中获取Bean对象得实例,如果获取不到,则触发Bean对象的创建方法createBean。
Bean根据作用域划有很多种,日常主要打交道的还是单例的比较多,本篇主要详细讲解单例bean的创建,其他的不做展开。

二 源码

2.1 getBean

public Object getBean(String name) throws BeansException {
		//do开头方法才是实际干活
		return doGetBean(name, null, null, false);
}

2.2 doGetBean

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
        
        //去除BeanFactory实现类的BeanName的前缀标识符"&",解析别名等,获取真正beanName
		final String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
        //从缓存中获取Bean的对象
        //如果Bean对象非单例,那么一级缓存中是不会缓存这个Bean对象
		Object sharedInstance = getSingleton(beanName);
      //sharedInstance不为空,说明Bean已经实例化过
		if (sharedInstance != null && args == null) {
		    //省略日志
           //这里有个问题,一级缓存中已经存在beanName和完整bean对象的映射,为什么还需要再获取一次?这是因为存在FactoryBean这类特殊的bean,他们并没有存放到一级缓存中                  
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
            //  针对原型bean产生的循环依赖(无论哪种注入方式),直接抛出异常
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
            //获取父类BeanFactory
			BeanFactory parentBeanFactory = getParentBeanFactory();
            //父类BeanFactory不为空且当前beanName的BeanDefinition不存在
            //尝试从parentBeanFactory中获取bean实例
			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) {
					// Delegation to parent with explicit args.
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else if (requiredType != null) {
					// No args -> delegate to standard getBean method.
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}

			if (!typeCheckOnly) {
              //检查beanName是否缓存在alreadyCreated,若无则添加进去
				markBeanAsCreated(beanName);
			}

			try {
              //获取合并后的RootBeanDefinition
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                
                //检查bean是否为被定义为抽象
				checkMergedBeanDefinition(mbd, beanName, args);

				// Guarantee initialization of beans that the current bean depends on.
               //获取实例化当前bean前需要依赖的所有bean
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dep : dependsOn) {
				     //注册bean的依赖关系
						registerDependentBean(dep, beanName);
						try {
                        //获取dep实例,如果没有则触发初始化
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
			            //异常处理
						}
					}
				}
          
				// Create bean instance.                             
           //根据不同的bean作用域进行bean的创建,分为三种1)单例 2)原型 3)其他,大部分使用场景都是单例的bean,因此重点讲解单例方式!
                
              //mdb是单例
				if (mbd.isSingleton()) {
                 //getSingleton里面再次判断beanName有没有在缓存中,没用则使用createBean实例化Bean
					sharedInstance = getSingleton(beanName, () -> {
						try {
                        //实例化Bean,执行构造函数
                    
							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对象
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
            
               //mdb是原型类型
               //每次都创建一个新的bean对象,且不会放入三级缓存中
				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);
				}
                
                //mbd作用域非单例和原型
				else {
					String scopeName = mbd.getScope();
					final Scope scope = this.scopes.get(scopeName);
					if (scope == null) {
						//抛出异常
					}
					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) {
					//抛出异常
					}
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		// Check if required type matches the type of the actual bean instance.
        //requiredType不为空且bean不属于requiredType的实例,说明类型不满足要求
        
		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) {
				//抛出异常
			}
		}
		return (T) bean;
	}

2.3 isPrototypeCurrentlyInCreation

    //判断该beanName对应的bean是否为正在创建的原型bean
	protected boolean isPrototypeCurrentlyInCreation(String beanName) {
		Object curVal = this.prototypesCurrentlyInCreation.get();
		return (curVal != null &&
				(curVal.equals(beanName) || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName))));
	}

2.4 markBeanAsCreated方法

protected void markBeanAsCreated(String beanName) {
        //判断是否已经创建
		if (!this.alreadyCreated.contains(beanName)) {
          //双检查锁
			synchronized (this.mergedBeanDefinitions) {
				if (!this.alreadyCreated.contains(beanName)) {
					// Let the bean definition get re-merged now that we're actually creating
					// the bean... just in case some of its metadata changed in the meantime.
                  //将beanName对应的RootBeanDefinition的state修改为ture,
                  表示需要重新合并
					clearMergedBeanDefinition(beanName);
                    //将当前beanName标记为已经创建
					this.alreadyCreated.add(beanName);
				}
			}
		}
	}
        
    
 protected void clearMergedBeanDefinition(String beanName) {
		RootBeanDefinition bd = this.mergedBeanDefinitions.get(beanName);
		if (bd != null) {
			bd.stale = true;
		}
	}

2.5 checkMergedBeanDefinition方法

protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, @Nullable Object[] args)
			throws BeanDefinitionStoreException {
        //判断bean是否为抽象的,若是则抛出异常
        //抽象是指自身不会实例化,仅作为子bean的父类而已
		if (mbd.isAbstract()) {
			throw new BeanIsAbstractException(beanName);
		}
	}

2.6 getSingleton

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "Bean name must not be null");
		synchronized (this.singletonObjects) {
			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 + "'");
				}
				beforeSingletonCreation(beanName);
                
                //标志是否为新创建的单例bean对象
				boolean newSingleton = false;
                
            //suppressedExceptions记录抑制异常
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
                //ObjectFactory为函数式接口,执行getObject方法才会触发入参函数(createBean(beanName, mbd, args)方法)的执行
                //实例化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) {
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}

2.7 beforeSingletonCreation

    //缓存从创建检查中排除的bean的名称
	private final Set<String> inCreationCheckExclusions =
			Collections.newSetFromMap(new ConcurrentHashMap<>(16));

    //缓存正在创建的单例bean
	private final Set<String> singletonsCurrentlyInCreation =
			Collections.newSetFromMap(new ConcurrentHashMap<>(16));


protected void beforeSingletonCreation(String beanName) {
        //当前beanName不存在创建时候检查排除的缓存(inCreationCheckExclusions)中且添加到正在创建缓存(singletonsCurrentlyInCreation)失败
		if (!this.inCreationCheckExclusions.contains(beanName) &&!this.singletonsCurrentlyInCreation.add(beanName)) {
             //抛出异常
			throw new BeanCurrentlyInCreationException(beanName);
		}
	}

2.8 afterSingletonCreation

protected void afterSingletonCreation(String beanName) {
          //当前beanName不存在创建时候检查排除的缓存(inCreationCheckExclusions)中且从正在创建缓存(singletonsCurrentlyInCreation)中移除失败
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
			throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
		}
	}

2.9 addSingleton

protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
            //添加到一级缓存
			this.singletonObjects.put(beanName, singletonObject);
            //从二级和三级缓存中删除
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
            //添加到存储按注册顺序排列的集合中
            //注册值为bean的名称
			this.registeredSingletons.add(beanName);
		}
	}

2.10 getObjectForBeanInstance

protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

		String currentlyCreatedBean = this.currentlyCreatedBean.get();
		if (currentlyCreatedBean != null) {
			registerDependentBean(beanName, currentlyCreatedBean);
		}
        
        //这里入参的name和beanName是有区别,beanName是name去除别名/"&"前缀后的名字,如实现FactoryBean接口这类特殊的bean,name是带"&"前缀,而beanName则没用
		return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd);
	}


protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

		// Don't let calling code try to dereference the factory if the bean isn't a factory.
        //判断beanName是否不为空且开头为"&"
        //实现BeanFactory接口的bean的beanName开头为"&"
		if (BeanFactoryUtils.isFactoryDereference(name)) {
            //为空bean的实例
			if (beanInstance instanceof NullBean) {
             //直接返回
				return beanInstance;
			}
            //不为FactoryBean的实例,抛出异常
            //说明没有实现FactoryBean接口的bean,命名时候不要以"&",否则SPringle检测到会抛出异常
			if (!(beanInstance instanceof FactoryBean)) {
				throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
			}
            
            //mbd不为空,则将isFactoryBean属性设置为true
			if (mbd != null) {
				mbd.isFactoryBean = true;
			}
			return beanInstance;
		}

		// Now we have the bean instance, which may be a normal bean or a FactoryBean.
		// If it's a FactoryBean, we use it to create a bean instance, unless the
		// caller actually wants a reference to the factory.
      //beanInstance不是FactoryBean的实例       
        if (!(beanInstance instanceof FactoryBean)) {
			return beanInstance;
		}

        //beanInstance是FactoryBean的实例但是beanName却没用以"&"开头
		Object object = null;
		if (mbd != null) {
			mbd.isFactoryBean = true;
		}
		else {
          //以beanName为key,从factoryBeanObjectCache缓存中获取bean的实例
			object = getCachedObjectForFactoryBean(beanName);
		}
        
        //factoryBeanObjectCache中没用缓存当前beanName
		if (object == null) {
			// Return bean instance from factory.
            //转型
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			// Caches object obtained from FactoryBean if it is a singleton.
            //mbd不为空且containsBeanDefinition中含有当前beanName
			if (mbd == null && containsBeanDefinition(beanName)) {
                //获取合并的bean定义
				mbd = getMergedLocalBeanDefinition(beanName);
			}
            //i mbd.isSynthetic():判断bean definition是否为合成的
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}

2.11 getObjectFromFactoryBean

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
        //判断bean是否为单例且一级缓存singletonObjects中缓存当前beanName
		if (factory.isSingleton() && containsSingleton(beanName)) {
        //加锁
			synchronized (getSingletonMutex()) {
            //从缓存factoryBeanObjectCache中获取
				Object object = this.factoryBeanObjectCache.get(beanName);
                //缓存不存在
				if (object == null) {
                   //从FactoryBean的实现类的getObject()方法获取
					object = doGetObjectFromFactoryBean(factory, beanName);
					// Only post-process and store if not put there already during getObject() call above
					// (e.g. because of circular reference processing triggered by custom getBean calls)
                    //再次从缓存factoryBeanObjectCache中获取bean对象,主要是因为循环依赖
					Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
					if (alreadyThere != null) {
                    //使用缓存进行覆盖
						object = alreadyThere;
					}
					else {
                    // 是否需要后置处理
						if (shouldPostProcess) {
                        //当前bean是否生长创建
							if (isSingletonCurrentlyInCreation(beanName)) {
								// Temporarily return non-post-processed object, not storing it yet..
								return object;
							}
                            
                            //创建前检查
							beforeSingletonCreation(beanName);
							try {
                            //进行后置处理,返回生成的对象
                            //调用后置处理器的postProcessAfterInitialization方法
								object = postProcessObjectFromFactoryBean(object, beanName);
							}
							catch (Throwable ex) {
								throw new BeanCreationException(beanName,
										"Post-processing of FactoryBean's singleton object failed", ex);
							}
							finally {
                            //创建后检查
								afterSingletonCreation(beanName);
							}
						}
						if (containsSingleton(beanName)) {
                        
                        //将键值对(beanName,object)添加到factoryBeanObjectCache缓存中
							this.factoryBeanObjectCache.put(beanName, object);
						}
					}
				}
				return object;
			}
		}
		else {
         //从FactoryBean的实现类的getObject()方法获取
			Object object = doGetObjectFromFactoryBean(factory, beanName);
			  // 是否需要后置处理
            if (shouldPostProcess) {
				try {
                  //调用后置处理器的postProcessAfterInitialization方法,作用于该bean
					object = postProcessObjectFromFactoryBean(object, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
				}
			}
         //返回bean对象
			return object;
		}
	}

2.12 doGetObjectFromFactoryBean

	private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
			throws BeanCreationException {

		Object object;
		try {
             //系统安全验证
			if (System.getSecurityManager() != null) {
				AccessControlContext acc = getAccessControlContext();
				try {
					object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}
			else {
            //从FactoryBean实现类的getObject方法中获取对象
				object = factory.getObject();
			}
		}
		catch (FactoryBeanNotInitializedException ex) {
			throw new BeanCurrentlyInCreationException(beanName, ex.toString());
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
		}

		// Do not accept a null value for a FactoryBean that's not fully
		// initialized yet: Many FactoryBeans just return null then.
		//FactoryBean实现类的getObject方法也找不到
        if (object == null) {
			if (isSingletonCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(
						beanName, "FactoryBean which is currently in creation returned null from getObject");
			}
            
            //置为空bean
			object = new NullBean();
		}
        
        //返回bean对象
		return object;
	}

3 参考文献

1)JDK7在线文档
https://tool.oschina.net/apidocs/apidoc?api=jdk_7u4
2) JDK8在线文档
https://docs.oracle.com/javase/8/docs/api/
3)Spring Framework 5 中文文档
https://www.cntofu.com/book/95/index.html
4) Bruce Eckel. Java编程思想,第4版,2007,机械工业出版社
5)方腾飞,魏鹏,程晓明. Java并发编程的艺术,第1版,2015年,机械工业出版社
6)克雷格.沃斯. Spring实战,第5版,2020年,人民邮电出版社

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值