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的更多相关文章

  1. 从Spring容器中获取Bean。ApplicationContextAware

    引言:我们从几个方面有逻辑的讲述如何从Spring容器中获取Bean.(新手勿喷) 1.我们的目的是什么? 2.方法是什么(可变的细节)? 3.方法的原理是什么(不变的本质)? 1.我们的目的是什么? ...

  2. FastJson序列化Json自定义返回字段,普通类从spring容器中获取bean

    前言: 数据库的字段比如:price:1 ,返回需要price:1元. 这时两种途径修改: ① 比如sql中修改或者是在实体类转json前遍历修改. ②返回json,序列化时候修改.用到的是fastj ...

  3. 通过spring工具类获取bean

    package xxx; import org.springframework.beans.BeansException; import org.springframework.beans.facto ...

  4. spring工具类获取bean

    import org.springframework.web.context.ContextLoader; import org.springframework.web.context.WebAppl ...

  5. Spring - 运行时获取bean(ApplicationContextAware接口)

    默认情况下,我们的bean都是单例模式(即从容器初始化到销毁只保持一个实例).当一个bean需要引用另外一个bean,我们往往会通过bean属性的方式通过依赖注入来引用另外一个bean.那么问题就来了 ...

  6. Spring容器中获取bean实例的方法

    // 得到上下文环境 WebApplicationContext webContext = ContextLoader .getCurrentWebApplicationContext(); // 使 ...

  7. Tomcat启动后,从spring容器中获取Bean和ServletContext

    public static Object getBean(String beanName){ ApplicationContext context = ContextLoader.getCurrent ...

  8. 使用Spring容器动态注册和获取Bean

    有时候需要在运行时动态注册Bean到Spring容器,并根据名称获取注册的Bean.比如我们自己的SAAS架构的系统需要调用ThingsBoard API和Thingsboard交互,就可以通过Thi ...

  9. 【Spring】初始化Spring IoC容器(非Web应用),并获取Bean

    参考文章 Introduction to the Spring IoC container and beans BeanFactory 和ApplicationContext(Bean工厂和应用上下文 ...

随机推荐

  1. centos7 安装gitlab及简单配置

    1.安装 wget -O gitlab.rpm https://packages.gitlab.com/gitlab/gitlab-ce/packages/el/7/gitlab-ce-11.11.3 ...

  2. 2019面向对象程序设计(Java) 第17周-18周学习指导及要求

    2019面向对象程序设计(Java)第17周-18周学习指导及要求 (2019.12.20-2019.12.31)   学习目标 (1) 理解和掌握线程的优先级属性及调度方法: (2) 掌握线程同步的 ...

  3. 重新学习SpringMVC——基础

    2. SpringMVC_HelloWorld3. SpringMVC_RequestMapping_修饰类4. SpringMVC_RequestMapping_请求方式5. SpringMVC_R ...

  4. 搭建Dubbo Admin(五)

    Dubbo Admin下载地址(2019年9月8日):https://github.com/apache/dubbo-admin 注意:JDK要求1.8以上 1. 进入到模块 dubbo-admin- ...

  5. c语言命名规范图

    来自armbbs

  6. C# 集合根据属性去重筛选

    1.单个属性去重筛选 //去重筛选 var ChgDtlVoList = datas.Where((x, i) => datas.FindIndex(z => z.ChgId == x.C ...

  7. 使用ES6 Class封装的IndexDB 操作类,并实现模糊搜索

     封装如下: indexDBOperate.js export class IndexDBOperate { db = null // 数据库实例 databaseName = null // 数据库 ...

  8. CF1136E Nastya Hasn't Written a Legend(线段树)

    还能说什么呢,简直太妙了. $$a_{i+1}<a_i+k_i$$ $$a_{i+1}-k_i-k_{i-1}-\cdots-k_1<a_i+k_i-k_i-k_{i-1}-\cdots- ...

  9. [LeetCode] 878. Nth Magical Number 第N个神奇数字

    A positive integer is magical if it is divisible by either A or B. Return the N-th magical number.  ...

  10. [LeetCode] 148. Sort List 链表排序

    Sort a linked list in O(n log n) time using constant space complexity. Example 1: Input: 4->2-> ...