spring根据beanName获取bean

Posted xkzhangsanx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring根据beanName获取bean相关的知识,希望对你有一定的参考价值。

spring根据beanName获取bean主要实现:

org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(String, Class<T>, Object[], boolean)

    @SuppressWarnings("unchecked")
    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;
        
        // 直接尝试从缓存获取
        // Eagerly check singleton cache for manually registered singletons.
        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 + "‘");
                
            
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        

        else 
            // 原型模式循环依赖直接抛出异常(默认只有单例情况下才会尝试解决循环依赖问题)
            // Fail if we‘re already creating this bean instance:
            // We‘re assumably within a circular reference.
            if (isPrototypeCurrentlyInCreation(beanName)) 
                throw new BeanCurrentlyInCreationException(beanName);
            
            
            // 检查这个工厂中是否存在bean定义
            // Check if bean definition exists in this factory.
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) 
                // Not found -> check parent.
                String nameToLookup = originalBeanName(name);
                if (args != null) 
                    // Delegation to parent with explicit args.
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                
                else 
                    // No args -> delegate to standard getBean method.
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                
            

            if (!typeCheckOnly) 
                markBeanAsCreated(beanName);
            
            
            // 将存储xml配置文件的GernericBeanDefinition转换为RootBeanDefinition,如果指定的BeanName是子Bean的话同时会合并父类的相关属性
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);
            
            // 保证当前bean所依赖的bean的初始化(递归处理)
            // Guarantee initialization of beans that the current bean depends on.
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) 
                for (String dependsOnBean : dependsOn) 
                    getBean(dependsOnBean);
                    registerDependentBean(dependsOnBean, beanName);
                
            
            
            // bean的实例化
            // Create bean instance.
            if (mbd.isSingleton()) 
                sharedInstance = getSingleton(beanName, new ObjectFactory() 
                    public Object getObject() throws BeansException 
                        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 ‘" + scopeName + "‘");
                
                try 
                    Object scopedInstance = scope.get(beanName, new ObjectFactory() 
                        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的实际类型,如果不是进行类型转换
        // Check if required type matches the type of the actual bean instance.
        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());
            
        
        // 返回bean
        return (T) bean;
    

 

实际获取过程非常复杂,上面只是显示了获取的主要流程。

参考:spring源码深度解析

以上是关于spring根据beanName获取bean的主要内容,如果未能解决你的问题,请参考以下文章

Spring 获取单例流程

Spring 获取单例流程

Spring获取FactoryBean本身

spring怎么获取全部的bean

spring IOC之篇六 bean的加载---bean的创建

死磕 Spring----- IOC 之从单例缓存中获取单例 bean