当前位置 博文首页 > 南瓜灯cc:Spring源码分析之getBean主流程分析

    南瓜灯cc:Spring源码分析之getBean主流程分析

    作者:[db:作者] 时间:2021-08-12 15:08

    当我们通过向Spring容器获取某个bean的时候,总是调用Spring中重载的各种getBean方法。那么,getBean中的流程是什么样的?

    通过本文,你将对getBean方法的主流程有一个详细的认识。

    入口当然是getBean方法:

    	public Object getBean(String name) throws BeansException {
    		return doGetBean(name, null, null, false);
    	}
    	
    	protected <T> T doGetBean(
    			final String name, final Class<T> requiredType, final Object[] args, 
    			boolean typeCheckOnly)  throws BeansException {
    		//beanName转换,这里主要有两方面的考虑:
    		//1:如果beanName是以&开头的,则表明是要返回FactoryBean本身
    		//而不是其生产出来的对象,而FactoryBean存储的时候,跟普通的bean一样
    		//2:如果传入的是别名,则是需要转换为实际的beanName的			
    		final String beanName = transformedBeanName(name);
    		Object bean;
    
    		// 检查bean是否已经存在了缓存中
    		Object sharedInstance = getSingleton(beanName);
    		//不为空则表明之前被创建过
    		if (sharedInstance != null && args == null) {
    		       if (logger.isDebugEnabled()) {
    		           .............
    		       }
    		      //这里对于普通的bean,则会直接的返回,
    		      //如果是FactoryBean类型的则会创建对应的实例返回
    		     bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    		}
    		else {
    		     //如果是正在创建的Prototype类型的bean,无法处理该类型循环依赖的问题,则直接抛出异常信息		
    		    if (isPrototypeCurrentlyInCreation(beanName)) {
    			throw new BeanCurrentlyInCreationException(beanName);
    		    }
    
    		   // 查看父类中是否有相关的bean的定义信息
    		   BeanFactory parentBeanFactory = getParentBeanFactory();
    		   if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
    		  // 如果name是以&开头的  则返回&+beanName的格式
    		  String nameToLookup = originalBeanName(name);
    		  if (args != null) {
    		          //递归去父类中查找
    		          return (T) parentBeanFactory.getBean(nameToLookup, args);
    		  }else {
    		         //递归去父类中查找
    		        return parentBeanFactory.getBean(nameToLookup, requiredType);
    		  }
    	            }
    
    	           if (!typeCheckOnly) {
    		        markBeanAsCreated(beanName);
    	           }
    	           try {
    		//将父类的定义的BeanDefinition与子类的BeanDefinition进行合并覆盖
    		final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    		checkMergedBeanDefinition(mbd, beanName, args);
    
    		//判断bean是否有dependsOn 类的依赖
    		//如果没有循环依赖,则先创建所dependsOn依赖的bean
    		String[] dependsOn = mbd.getDependsOn();
    		if (dependsOn != null) {
    		 	for (String dep : dependsOn) {
    				//这里主要是判断是否有以下这种类型的依赖:
    				//<bean id="beanA" class="BeanA" depends-on="beanB">
    				//<bean id="beanB" class="BeanB" depends-on="beanA">
    				//如果有,则直接抛出异常
    				if (isDependent(beanName, dep)) {
    					.......
    				}
    				registerDependentBean(dep, beanName);
    				getBean(dep);
    			}
    		}
    
    		// 处理完bean的依赖关系,则开始来创建bean
    		if (mbd.isSingleton()) {
    		//创建单例的bean,这里的createBean下文将详细讲解
    		sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
    		@Override
    		public Object getObject() throws BeansException {
    			try {
    				return createBean(beanName, mbd, args);
    			}catch (BeansException ex) {
    				destroySingleton(beanName);
    			                throw ex;
    			}}});
    			bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    		}
    
    		else if (mbd.isPrototype()) {
    			//创建原型的bean
    			Object prototypeInstance = null;
    			try {
    				beforePrototypeCreation(beanName);
    				prototypeInstance = createBean(beanName, mbd, args);
    			}
    			finally {
    				afterPrototypeCreation(beanName);
    			}
    				bean = getObjectForBeanInstance(prototypeInstance, 
            name, beanName, mbd);
    			}
    
    		else {
    			//创建其他生命周期的bean
    			String scopeName = mbd.getScope();
    			final Scope scope = this.scopes.get(scopeName);
    			if (scope == null) {
    				.........
    			}
    			try {
    				Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
    					@Override
    					public Object getObject() throws BeansException {
    						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;
    			}
    		}
    
    		// bean的类型转换
    		if (requiredType != null && 
    bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
    			try {
    				return getTypeConverter().convertIfNecessary(bean, requiredType);
    			}
    			catch (TypeMismatchException ex) {
    				........
    			}
    		}
    		return (T) bean;
    	}
    

    整个getBean大的流程如上所示,在以上源码中,我们将看下以下的几个的方法:

    1:transformedBeanName方法:

    	protected String transformedBeanName(String name) {
    		//如果beanName是以&开头的  则截取掉开头的&
    		return canonicalName(BeanFactoryUtils.transformedBeanName(name));
    	}
    	public String canonicalName(String name) {
    		String canonicalName = name;
    		// 循环的去获取别名,直到获取到真实的beanName
    		//aliasA->aliasB->beanName
    		String resolvedName;
    		do {
    			resolvedName = this.aliasMap.get(canonicalName);
    			if (resolvedName != null) {
    				canonicalName = resolvedName;
    			}
    		}
    		while (resolvedName != null);
    		return canonicalName;
    	}
    
    

    2:getSingleton方法

    	public Object getSingleton(String beanName) {
    		return getSingleton(beanName, true);
    	}
    	//判断是否有缓存起来的bean
    	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    		//singletonObjects保存的为实例化并赋值过的bean,可以直接使用
    		Object singletonObject = this.singletonObjects.get(beanName);
    		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
    			synchronized (this.singletonObjects) {
    			//earlySingletonObjects主要是保存允许提前暴露出来的bean
    			//主要是为了解决循环依赖的问题
    			singletonObject = this.earlySingletonObjects.get(beanName);
    				if (singletonObject == null && allowEarlyReference) {
    				    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
    					if (singletonFactory != null) {
    						singletonObject = singletonFactory.getObject();
    						this.earlySingletonObjects.put(beanName, singletonObject);
    						this.singletonFactories.remove(beanName);
    					}
    				}
    			}
    		}
    		return (singletonObject != NULL_OBJECT ? singletonObject : null);
    	}

    3:getObjectForBeanInstance方法

    	protected Object getObjectForBeanInstance(
    			Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
    
    		//如果name是以&开头的 但是不是FactoryBean,则直接抛出异常
    		if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
    			throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
    		}
    
    		// 则beanInstance可能是一个普通的bean,也可能是一个FactoryBean
    		// 如果是一个普通的bean,则直接返回
    		if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
    			return beanInstance;
    		}
    
    		//FactoryBean创建出bean实例返回
    		Object object = null;
    		if (mbd == null) {
    			object = getCachedObjectForFactoryBean(beanName);
    		}
    		if (object == null) {
    			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
    			if (mbd == null && containsBeanDefinition(beanName)) {
    				mbd = getMergedLocalBeanDefinition(beanName);
    			}
    			boolean synthetic = (mbd != null && mbd.isSynthetic());
    			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
    		}
    		return object;
    	}
    

    以上对getBean主流程以及其主要的几个方法做了分析,下面将对其getBean的主流程做一个分析:

    通过流程图,将其主要的流程的轮廓给描述的出来。更加的直观。在下文中,我将对Spring中createBean做一个详细的描述

    ?

    cs