Spring getBean方法源码解析

User user = (User) beanFactory.getBean("user");

注:User为一普通bean

查看方法(AbstractBeanFactory#getBean

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

继续查看方法(AbstractBeanFactory#doGetBean

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
                          @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
   
    //一、提取beanName
    //这里主要做了两步工作
    //(1)去除name开头的所有&字符,即factoryBean的修饰符
    //(2)去aliasMap查找最终的beanName
    final String beanName = transformedBeanName(name);
    Object bean;

    // Eagerly check singleton cache for manually registered singletons.
    /*
		 * 这里是检查缓存中或者实例工厂中是否有对应的实例
		 * 原因:因为在创建单例bean的时候会存在依赖注入的情况。
		 * 而在创建依赖的时候为了避免循环依赖,Spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光,
		 * 也就是将ObjectFactory加入到缓存中,一旦下个bean创建的时候需要依赖上个bean则直接使用ObjectFactory
		 */
    //二、直接尝试从缓存获取或者从singletonFactories中的ObjectFactory
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
   
        if (logger.isTraceEnabled()) {
   
            if (isSingletonCurrentlyInCreation(beanName)) {
   
                logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                             "' that is not fully initialized yet - a consequence of a circular reference");
            }
            else {
   
                logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
            }
        }
        //三、当前的sharedInstance只是原始的bean状态,这里需要进一步加工处理
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }
    //四、如果没有找到,则直接创建实例
    else {
   
        // Fail if we're already creating this bean instance:
        // We're assumably within a circular reference.
        //只有在单例情况下才会尝试解决循环依赖
        //1、原型模式下,如果存在循环依赖,将会直接报错
        if (isPrototypeCurrentlyInCreation(beanName)) {
   
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // Check if bean definition exists in this factory.
        //2、如果所有已经加载的bean中不包括beanName,则尝试从parentBeanFactory中查找
        BeanFactory parentBeanFactory = getParentBeanFactory();
        //如果parentBeanFactory存在且当前的beanDefinitionMap不存在beanName的配置,
        //就只能调用parentBeanFactory的getBean方法去加载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) {
   
            markBeanAsCreated(beanName);
        }

        //3、手动加载bean
        try {
   
            //将存储XML配置信息的GenericBeanDefinition转换成RootBeanDefinition,
            //如果BeanName是子Bean的话同时会合并父类的相关属性
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);

            // Guarantee initialization of beans that the current bean depends on.
            String[] dependsOn = mbd.getDependsOn();
            //如果存在依赖则需要定义实例化依赖的bean
            if (dependsOn != null) {
   
                for (String dep : dependsOn) {
   
                    if (isDependent(beanName, dep)) {
   
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                                        "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }
                    registerDependentBean(dep, beanName);
                    try {
   
                        //递归调用getBean
                        getBean(dep);
                    }
                    catch (NoSuchBeanDefinitionException ex) {
   
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                                        "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                    }
                }
            }

            // Create bean instance.
            //实例化当前bean的所有依赖后便会实例化mbd本身了
            //下面是根据不同的scope类型来创建mbd

            //单例模式创建Bean
            if (mbd.isSingleton()) {
   
                sharedInstance = getSingleton(beanName, () -> {
   
                    try {
   
                        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 = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }
            //原型模式
            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);
            }
            //其余模式
            else {
   
                String scopeName = mbd.getScope();
                final Scope scope = this.scopes.get(scopeName);
                if (scope == null) {
   
                    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                }
                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) {
   
                    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);
                }
            }
        }
        catch (BeansException ex) {
   
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
    }

    // Check if required type matches the type of the actual bean instance.
    //8、如果传递了类型,则需要进行类型转换
    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) {
   
            if (logger.isTraceEnabled()) {
   
                logger.trace("Failed to convert bean '" + name + "' to required type '" +
                             ClassUtils.getQualifiedName(requiredType) + "'", ex);
            }
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    }
    return (T) bean;
}

上述方法就是获取bean的核心方法,我们一步一步拆解

一、首先我们需要对传递进来的name进行转换

代码如下:

protected String transformedBeanName(String name) {
   
    return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}

这里主要做了两件事

  • BeanFactoryUtils.transformedBeanName(name)

    public static String transformedBeanName(String name) {
         
        Assert.notNull(name, "'name' must not be null");
        if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
         
            return name;
        }
        return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
         
            do {
         
                beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
            }
            while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
            return beanName;
        });
    }
    

    该方法就是去除name的前缀中的所有&符号,这里的&符号主要是factoryBean的修饰符,如果name带有前缀&,表示获取当前的factoryBean,而非factoryBean返回的bean实例

  • canonicalName方法

    public String canonicalName(String name) {
         
        String canonicalName = name;
        // Handle aliasing...
        String resolvedName;
        do {
         
            resolvedName = this.aliasMap.get(canonicalName);
            if (resolvedName != null) {
         
                canonicalName = resolvedName;
            }
        }
        while (resolvedName != null);
        return canonicalName;
    }
    

    该方法就是去别名aliasMap中查找最终的beanName,例如aliasMap中,a->c,b->c,c不指向任何bean。那么当name输入a时返回的就是c。

二、尝试从缓存中加载bean

public Object getSingleton(String beanName) {
   
    //第二个参数true表示允许早期依赖
    return getSingleton(beanName, true);
}

进一步查看

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   
    //检查缓存中是否存在实例
    Object singletonObject = this.singletonObjects.get(beanName);
    //如果为空且singletonsCurrentlyInCreation存在该bean
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
   
        //锁定singletonObjects全局变量
        synchronized (this.singletonObjects) {
   
            //从earlySingletonObjects获取bean
            singletonObject = this.earlySingletonObjects.get(beanName);
            //如果获取不到且允许早期依赖
            if (singletonObject == null && allowEarlyReference) {
   
                //从singletonFactories获取ObjectFactory,这是因为有时候某些方法需要提前初始化的时候会
                //调用addSingletonFactory方法将对应的ObjectFactory初始化策略存储在singletonFactories
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                //如果不为空
                if (singletonFactory != null) {
   
                    //调用预先设定的getObject方法
                    singletonObject = singletonFactory.getObject();
                    //记录在缓存中
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    //earlySingletonObjects与singletonFactories是互斥的,因此这里需要remove
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return singletonObject;
}

Spring创建bean默认情况下是单例的,因此对于一个单例bean,Spring只会创建一次,后续再获取时直接从缓存中加载。由于可能存在的循环依赖(例如A依赖B,B依赖A),因此Spring为了解决循环依赖,创建bean的原则是不等bean创建完成就将创建bean的ObjectFactory提早曝光到缓存中,一旦下一个bean创建时候需要时直接使用ObjectFactory。这里涉及到三级缓存

/** Cache of singleton objects: bean name to bean instance.
	 *  保存beanName和bean实例之间的关系,即beanName-->bean实例
	 */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

/** Cache of singleton factories: bean name to ObjectFactory.
	 *  保存beanName和创建bean的工厂之间的关系,即beanName-->ObjectFactory实例
	 */
private final Map<String, 
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值