Spring源码分析 Bean创建和获取

Spring源码分析 Bean创建和获取

Spring获取Bean源码

public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}
	protected Object doGetBean(String name, Class requiredType, final Object args[], boolean typeCheckOnly)
        throws BeansException
    {
        final String beanName;
        Object bean;
        final RootBeanDefinition mbd;
        Object prototypeInstance;
        beanName = transformedBeanName(name);
        // 先尝试从缓存中获取bean,对于那些单例模式的Bean,缓存获取
        Object sharedInstance = getSingleton(beanName);
        if(sharedInstance != null && args == null)
        {
            if(logger.isDebugEnabled())
                if(isSingletonCurrentlyInCreation(beanName))
                    logger.debug((new StringBuilder()).append("Returning eagerly cached instance of singleton bean '").append(beanName).append("' that is not fully initialized yet - a consequence of a circular reference").toString());
                else
                    logger.debug((new StringBuilder()).append("Returning cached instance of singleton bean '").append(beanName).append("'").toString());
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
            break MISSING_BLOCK_LABEL_544;
        }
        if(isPrototypeCurrentlyInCreation(beanName))
            throw new BeanCurrentlyInCreationException(beanName);
        BeanFactory parentBeanFactory = getParentBeanFactory();
        if(parentBeanFactory != null && !containsBeanDefinition(beanName))
        {
            String nameToLookup = originalBeanName(name);
            if(args != null)
                return parentBeanFactory.getBean(nameToLookup, args);
            else
                return parentBeanFactory.getBean(nameToLookup, requiredType);
        }
        if(!typeCheckOnly)
            markBeanAsCreated(beanName);
        mbd = getMergedLocalBeanDefinition(beanName);
        checkMergedBeanDefinition(mbd, beanName, args);
        String dependsOn[] = mbd.getDependsOn();
        if(dependsOn != null)
        {
            String arr$[] = dependsOn;
            int len$ = arr$.length;
            for(int i$ = 0; i$ < len$; i$++)
            {
                String dependsOnBean = arr$[i$];
                getBean(dependsOnBean);
                registerDependentBean(dependsOnBean, beanName);
            }

        }
        if(mbd.isSingleton())
        {
            sharedInstance = getSingleton(beanName, new ObjectFactory() {

                public Object getObject()
                    throws BeansException
                {
                    try
                    {
                        return createBean(beanName, mbd, args);
                    }
                    catch(BeansException ex)
                    {
                        destroySingleton(beanName);
                        throw ex;
                    }
                }

                final String val$beanName;
                final RootBeanDefinition val$mbd;
                final Object val$args[];
                final AbstractBeanFactory this$0;

            
            {
                this$0 = AbstractBeanFactory.this;
                beanName = s;
                mbd = rootbeandefinition;
                args = aobj;
                super();
            }
            }
);
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            break MISSING_BLOCK_LABEL_544;
        }
        if(!mbd.isPrototype())
            break MISSING_BLOCK_LABEL_399;
        prototypeInstance = null;
        beforePrototypeCreation(beanName);
        prototypeInstance = createBean(beanName, mbd, args);
        afterPrototypeCreation(beanName);
        break MISSING_BLOCK_LABEL_383;
        Exception exception;
        exception;
        afterPrototypeCreation(beanName);
        throw exception;
        bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
        break MISSING_BLOCK_LABEL_544;
        String scopeName = mbd.getScope();
        Scope scope = (Scope)scopes.get(scopeName);
        if(scope == null)
            throw new IllegalStateException((new StringBuilder()).append("No Scope registered for scope '").append(scopeName).append("'").toString());
        try
        {
            Object scopedInstance = scope.get(beanName, new ObjectFactory() {

                public Object getObject()
                    throws BeansException
                {
                    beforePrototypeCreation(beanName);
                    Object obj = createBean(beanName, mbd, args);
                    afterPrototypeCreation(beanName);
                    return obj;
                    Exception exception1;
                    exception1;
                    afterPrototypeCreation(beanName);
                    throw exception1;
                }

                final String val$beanName;
                final RootBeanDefinition val$mbd;
                final Object val$args[];
                final AbstractBeanFactory this$0;

            
            {
                this$0 = AbstractBeanFactory.this;
                beanName = s;
                mbd = rootbeandefinition;
                args = aobj;
                super();
            }
            }
);
            bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
        }
        catch(IllegalStateException ex)
        {
            throw new BeanCreationException(beanName, (new StringBuilder()).append("Scope '").append(scopeName).append("' is not active for the current thread; ").append("consider defining a scoped proxy for this bean if you intend to refer to it from a singleton").toString(), ex);
        }
        if(requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass()))
        {
            try
            {
                return getTypeConverter().convertIfNecessary(bean, requiredType);
            }
            catch(TypeMismatchException ex)
            {
                if(logger.isDebugEnabled())
                    logger.debug((new StringBuilder()).append("Failed to convert bean '").append(name).append("' to required type [").append(ClassUtils.getQualifiedName(requiredType)).append("]").toString(), ex);
            }
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        } else
        {
            return bean;
        }
    }

如图所示,源码分析
首先获取bean的名称 beanName = transformedBeanName(name);
然后查看缓存中bean是否存在,如下图

Object sharedInstance = getSingleton(beanName);
private final Map singletonObjects = new ConcurrentHashMap(64);
private final Map alreadyCreated;
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		
		/*1*/
		Object singletonObject = singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName))
			synchronized (singletonObjects) {
				singletonObject = earlySingletonObjects.get(beanName);
				if (singletonObject == null && allowEarlyReference) {
					ObjectFactory singletonFactory = (ObjectFactory) singletonFactories
							.get(beanName);
					if (singletonFactory != null) {
						singletonObject = singletonFactory.getObject();
						earlySingletonObjects.put(beanName, singletonObject);
						singletonFactories.remove(beanName);
					}
				}
			}
		return singletonObject == NULL_OBJECT ? null : singletonObject;
	}
	
	/*2*/
	protected void markBeanAsCreated(String beanName) {
		alreadyCreated.put(beanName, Boolean.TRUE);
}
/*3*/
String dependsOn[] = mbd.getDependsOn();
    if(dependsOn != null)
    {
        String arr$[] = dependsOn;
        int len$ = arr$.length;
        for(int i$ = 0; i$ < len$; i$++)
        {
            String dependsOnBean = arr$[i$];
            getBean(dependsOnBean);
            registerDependentBean(dependsOnBean, beanName);
        }

    }

紧接着,如图1 通过singletonObjects缓存对象去获取对象,由于可见,Spring底层用的缓存大多数是缓存在Map结构中,缓存对象首次初始化的时候为空,构建之前会先调用 如图2-markBeanAsCreated()标明此处bean状态为构建中, 继续分析如下
如图3 后续会查看当前bean是否有依赖引用,如A依赖B,首先会把B创建成功后,然后注入到A中
下叙真实获取bean对象源码

public static transient Object instantiateClass(Constructor ctor,
			Object args[]) throws BeanInstantiationException {
		Assert.notNull(ctor, "Constructor must not be null");
		try {
			ReflectionUtils.makeAccessible(ctor);
			return ctor.newInstance(args);
		} catch (InstantiationException ex) {
			throw new BeanInstantiationException(ctor.getDeclaringClass(),
					"Is it an abstract class?", ex);
		} catch (IllegalAccessException ex) {
			throw new BeanInstantiationException(ctor.getDeclaringClass(),
					"Is the constructor accessible?", ex);
		} catch (IllegalArgumentException ex) {
			throw new BeanInstantiationException(ctor.getDeclaringClass(),
					"Illegal arguments for constructor", ex);
		} catch (InvocationTargetException ex) {
			throw new BeanInstantiationException(ctor.getDeclaringClass(),
					"Constructor threw exception", ex.getTargetException());
		}
	}
	public static void makeAccessible(Constructor ctor) {
	if ((!Modifier.isPublic(ctor.getModifiers()) || !Modifier.isPublic(ctor
			.getDeclaringClass().getModifiers())) && !ctor.isAccessible())
		ctor.setAccessible(true);
}

由此得出结论,bean创建实例是通过java反射来实现,创建之前会检查访问修饰类型,如果不是public可见的,调用setAccessible(true);得到私有构造方法来构建对象实例,接下来要把bean中默认设置的属性值注入,创建出来的单例bean对象添加到缓存中,供下次直接使用,到此bean创建和获取流程结束

protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (singletonObjects) {
			//Map缓存单例bean对象
			singletonObjects.put(beanName,
					singletonObject == null ? NULL_OBJECT : singletonObject);
			singletonFactories.remove(beanName);
			earlySingletonObjects.remove(beanName);
			registeredSingletons.add(beanName);
		}
	}

总结:

SpringBean创建和获取

  • Spring的bean实际上是缓存在CurrentHashMap对象中
  • 创建bean之前,首先要将该bean的创建标识设定好,表示该bean已经即将被创建,其目的增强缓存效率
  • 根据bean的Scope属性来确定是singleton还是prototype等范围,然后创建相应bean对象
  • 通过java反射创建bean的实例
  • 接下来,寻找bean的属性值,完成属性注入
  • 将所创建出来的singleton对象添加到缓存中,供下次调用使用

作者简介:张程 技术研究

更多文章请关注微信公众号:zachary分解狮 (frankly0423)
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章