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的主要内容,如果未能解决你的问题,请参考以下文章