spring源码深度解析——bean的加载

本文深入解析Spring框架中AbstractBeanFactory的doGetBean方法,详细阐述了Spring如何处理单例和原型bean的创建过程,特别是在解决循环依赖问题上的独特机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean

方法

	protected <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
        //提取对应的beanName
        final String beanName = transformedBeanName(name);
        Object bean;
        /*
        * 检查缓存中或者实例工厂中是否有对应的实例
        * 为什么首先会使用这段代码呢,
        * 因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,
        * Spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光
        * 也就是将ObjectFactory加入到缓存中,一旦下个bean创建时候需要依赖上个bean则直接使用
ObjectFactory
        */
        //直接尝试从缓存获取或者singletonFactories中的ObjectFactory中获取
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            if (logger.isDebugEnabled()) {
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.debug("Returning eagerly cached instance of singleton bean'" + beanName +"' that is not fully initialized yet - a consequence of
a circular reference");
                }
else {
logger.debug("Returning cached instance of singleton bean '" +
beanName + "'");
}
            }
//返回对应的实例,有时候存在诸如BeanFactory的情况并不是直接返回实例本身而是返回指定方法返回的实例
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }else {
            //只有在单例情况才会尝试解决循环依赖,原型模式情况下,如果存在
            //A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未创建完的时候因为
            //对于B的创建再次返回创建A,造成循环依赖,也就是下面的情况
            //isPrototypeCurrentlyInCreation(beanName)为true
            if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
            }
            BeanFactory parentBeanFactory = getParentBeanFactory();
            //如果 beanDefinitionMap 中也就是在所有已经加载的类中不包括 beanName 则尝试从
parentBeanFactory中检测
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                 String nameToLookup = originalBeanName(name);
                 //递归到BeanFactory中寻找
                 if (args != null) {
                      return (T) parentBeanFactory.getBean(nameToLookup, args);
                 }
                 else {
                     return parentBeanFactory.getBean(nameToLookup, requiredType);
                 }
            }
            //如果不是仅仅做类型检查则是创建bean,这里要进行记录
            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }
//将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition,如果指
定BeanName是子Bean的话同时会合并父类的相关属性
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);
            String[] dependsOn = mbd.getDependsOn();
            //若存在依赖则需要递归实例化依赖的bean
            if (dependsOn != null) {
                 for (String dependsOnBean : dependsOn) {
                      getBean(dependsOnBean);
                      //缓存依赖调用
                      registerDependentBean(dependsOnBean, beanName);
                 }
            }
            //实例化依赖的bean后便可以实例化mbd本身了
            //singleton模式的创建
            if (mbd.isSingleton()) {
                sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                    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()) {
             //prototype模式的创建(new)
             Object prototypeInstance = null;
             try {
                 beforePrototypeCreation(beanName);
                 prototypeInstance = createBean(beanName, mbd, args);
             }
             finally {
                  afterPrototypeCreation(beanName);
             } 
             bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
        }else {
            //指定的scope上实例化bean
            String scopeName = mbd.getScope();
            final Scope scope = this.scopes.get(scopeName);
            if (scope == null) {
                 throw new IllegalStateException("No Scope registered for scope '"
+ scopeName + "'"); 
            }
            try {
                Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
                     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) {

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);
              }
          }
     }
        //检查需要的类型是否符合bean的实际类型
        if (requiredType != null && bean != null && !requiredType.isAssignableFrom
(bean.getClass())) {
            try {
                return getTypeConverter().convertIfNecessary(bean, requiredType);
            }
            catch (TypeMismatchException ex) {
                 if (logger.isDebugEnabled()) {
                      logger.debug("Failed to convert bean '" + name + "' to required type
[" +
                              ClassUtils.getQualifiedName(requiredType) + "]", ex);
                 }
                 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.
getClass());
            }
        }
        return (T) bean;
}

}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值