bean的构建(一)

简介: bean的构建

bean的构建

  1. createBean调用堆栈
  2. 基本思路如下:
  1. beanName的转换
  2. 从缓存中加载单例bean
  3. 对bean进行实例化
  4. 原型模式检查
  5. BeanDefinition转化为RootBeanDefinition
  6. 加载bean的依赖
  7. 针对不同的域进行bean的创建
  8. bean的类型转换
  • doGetBean总纲:
  • 获取bean:
  • 合并bean定义:
  • 获取当前bean的依赖:
  • 创建Bean:

doGetBean

protected<T> T doGetBean(
        String name,@Nullable Class<T> requiredType,@Nullable Object[]args,boolean typeCheckOnly)
        throws BeansException{
        //对于beanName的转换
        //因为可能会存在FactoryBean或者bean的别名指向别的bean
        String beanName=transformedBeanName(name);
        Object bean;
        //此处解决了单例bean的循环依赖问题,提前暴露了bean的ObjectFactory或者bean本身,
        // 如果其余bean存在依赖,则直接获取,从而解决了循环依赖
        //从缓存或者ObjectFactory中获取bean实例
        Object sharedInstance=getSingleton(beanName);
        //如果可以从缓存中或者ObjectFactory中获取beanInstance
        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+"'");
        }
        }
        //对bean类型的检测;bean可能为空,bean可能是以&开头的FactoryBean,也可能是仿造FactoryBean的错误Bean
        bean=getObjectForBeanInstance(sharedInstance,name,beanName,null);
        }
        //如果不能从缓存中或者ObjectFactory中获取beanInstance
        else{
        //Spring只会解决单例bean的循环依赖(因为原型bean无法保存bean的状态,以至于无法提前暴露bean),
        //如果存在原型的循环依赖,则显示抛出异常
        if(isPrototypeCurrentlyInCreation(beanName)){
        throw new BeanCurrentlyInCreationException(beanName);
        }
        // Check if bean definition exists in this factory.
        //获取父级beanFactory
        BeanFactory parentBeanFactory=getParentBeanFactory();
        //如果父级beanFactory不为空,且自身BeanDefinition的Map集合不包含key为beanName的key
        if(parentBeanFactory!=null&&!containsBeanDefinition(beanName)){
        //自身没有key为beanName的key,则查找父级beanFactory(parentBeanFactory)
        //获取bean的名称,主要是区分普通Bean以及FactoryBean
        String nameToLookup=originalBeanName(name);
        //递归查询bean并且返回bean的instance
        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);
        }
        try{
        //将子bean定义以及父bean定义合并,并且转化为RootBeanDefinition
        RootBeanDefinition mbd=getMergedLocalBeanDefinition(beanName);
        //检查BeanDefinition必须非抽象,如果是抽象,则直接抛出异常
        checkMergedBeanDefinition(mbd,beanName,args);
        //获取当前bean所依赖的bean,先实例化自身依赖的bean
        String[]dependsOn=mbd.getDependsOn();
        //如果自身bean存在依赖bean
        if(dependsOn!=null){
        for(String dep:dependsOn){
        //确定指定的依赖 bean 是否已注册为依赖于给定 bean 或其任何传递依赖项
        //确定自身bean是否已经注册为自身bean的任何依赖项;如果已经注册,则认为当前bean依赖于自身,存在循环依赖
        //否则注册自身所依赖的bean
        if(isDependent(beanName,dep)){
        throw new BeanCreationException(mbd.getResourceDescription(),beanName,
        "Circular depends-on relationship between '"+beanName+"' and '"+dep+"'");
        }
        //缓存中注册自身所依赖的所有bean
        registerDependentBean(dep,beanName);
        try{
        //递归创建自身所依赖的bean
        getBean(dep);
        }
        catch(NoSuchBeanDefinitionException ex){
        throw new BeanCreationException(mbd.getResourceDescription(),beanName,
        "'"+beanName+"' depends on missing bean '"+dep+"'",ex);
        }
        }
        }
        // 创建bean的实例
        // 创建bean->初始化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();
        if(!StringUtils.hasLength(scopeName)){
        throw new IllegalStateException("No scope name defined for bean ´"+beanName+"'");
        }
        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.
        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;
        }
目录
相关文章
|
6月前
|
Java 开发者 Spring
Spring中获取Bean对象的三种注入方式和两种注入方法
Spring中获取Bean对象的三种注入方式和两种注入方法
|
11月前
|
Java C# Spring
Spring中Bean实例化过程中的initializeBean方法
Spring中Bean实例化过程中的initializeBean方法
91 0
|
XML Java 数据库连接
“Spring管理JavaBean的过程及Bean的生命周期“
“Spring管理JavaBean的过程及Bean的生命周期“
118 0
|
6月前
|
XML Java 数据格式
Spring Bean的定义(含创建Bean的三种方式)
Spring Bean的定义(含创建Bean的三种方式)
|
6月前
|
Java Spring
flowable 监听器无法获取spring bean ,自动注入bean为null,解决方案
flowable 监听器无法获取spring bean ,自动注入bean为null,解决方案
|
Java Spring 容器
Spring Bean实例化流程
Spring Bean实例化流程
|
缓存 Java Spring
|
Java Spring 容器
Spring构造通过工厂创建bean
Spring构造通过工厂创建bean
|
XML 数据格式
Sping5学习(五):IOC操作Bean管理 之 基于注解方式的属性注入
Sping5学习(五):IOC操作Bean管理 之 基于注解方式的属性注入
Sping5学习(五):IOC操作Bean管理 之 基于注解方式的属性注入
|
Oracle Java 关系型数据库
Spring基础篇:通过@Component标注的类注入到其他Bean中
通过@Component标注的类注入到其他Bean中
446 0