面试官:讲一下SpringBean的生命周期

大家好,我是一安,Spring Bean生命周期作为面试必问题,今天特意分享一篇有关Spring Bean生命周期介绍,前面有介绍一篇《大厂Java二面:Spring是如何解决循环依赖的问题

简要概括

面试官:讲一下SpringBean的生命周期简要总结为4 个阶段:

  • 实例化:第 1 步,实例化一个 bean 对象;
  • 属性赋值:第 2 步,为 bean 设置相关属性和依赖;
  • 初始化:第 3~7 步,第 3、4 步为在初始化前执行,第 5、6 步为初始化操作,第 7 步在初始化后执行,该阶段结束,才能被用户使用;
  • 销毁:第 8和10~11步,第8步不是真正意义上的销毁(还没使用呢),而是使用前先注册了销毁的相关调用接口,后面第10、11步真正销毁时才执行相应的方法。

详细说明

创建Bean之前

面试官:讲一下SpringBean的生命周期

对应的代码在AbstractAutowireCapableBeanFactory类的createBean方法中:

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
  
  ......
  ......
  
  public <T> T createBean(Class<T> beanClass) throws BeansException {
      RootBeanDefinition bd = new RootBeanDefinition(beanClass);
      bd.setScope("prototype");
      bd.allowCaching = ClassUtils.isCacheSafe(beanClass, this.getBeanClassLoader());
      return this.createBean(beanClass.getName(), bd, (Object[])null);
  }
  
  ......
  ......
  
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
      if (this.logger.isTraceEnabled()) {
          this.logger.trace("Creating instance of bean '" + beanName + "'");
      }
      //从AbstractBeanFactory的doGetBean传递过来的父子容器合并BeanDefinition
      RootBeanDefinition mbdToUse = mbd;
      Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
      if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
          //克隆一份BeanDefinition,用来设置上加载出来的class对象
          //之所以后续用该副本操作,是因为不希望将解析的class绑定到缓存里的BeanDefinition
          //因为class有可能是每次都需要动态解析出来的
          mbdToUse = new RootBeanDefinition(mbd);
          mbdToUse.setBeanClass(resolvedClass);
      }
       // Prepare method overrides.
      //校验和准备Bean中的方法覆盖
      try {
          //如果是0个则抛异常,如果是1个也就没有重载的必要
          mbdToUse.prepareMethodOverrides();
      } catch (BeanDefinitionValidationException var9) {
          throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var9);
      }

      Object beanInstance;
      try {
             // 给BeanPostProcessors一个机会来返回代理来替代真正的实例,应用实例化前的前置处理器,用户自定义动态代理的方式,针对于当前的被代理类需要经过标准的代理流程来创建对象
          beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
          if (beanInstance != null) {
              return beanInstance;
          }
      } catch (Throwable var10) {
          throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10);
      }

      try {
          // 实际创建bean的调用
          beanInstance = this.doCreateBean(beanName, mbdToUse, args);
          if (this.logger.isTraceEnabled()) {
              this.logger.trace("Finished creating instance of bean '" + beanName + "'");
          }

          return beanInstance;
      } catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
          throw var7;
      } catch (Throwable var8) {
          throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8);
      }
  }
    
  ......
  ......
  
}

创建Bean

面试官:讲一下SpringBean的生命周期对应的实现在AbstractAutowireCapableBeanFactory类的doCreateBean方法中:

    protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
          // BeanWrapper封装了具体的Bean实例,然后可以很方便地通过调用getPropertyValue和setPropertyValue等方法反射读写Bean的具体属性
        BeanWrapper instanceWrapper = null;
        //拿到Bean的普通实例,这里的普通实例是相对AOP代理的那种Bean而言的。普通bean大部分都是通过反射拿到构造方法创建实例对象
        if (mbd.isSingleton()) {
            instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
        }

        if (instanceWrapper == null) {
            // 调用构造方法创建一个空实例对象,并用BeanWrapper进行包装
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }

        Object bean = instanceWrapper.getWrappedInstance();
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }

        synchronized(mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                } catch (Throwable var17) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
                }

                mbd.postProcessed = true;
            }
        }
        //创建这个Bean的ObjectFactory的对象,并且把他加到第三级缓存中,主要用来解决循环依赖
        boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
        if (earlySingletonExposure) {
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
            }
          /**
            * 循环依赖处理逻辑:将已完成实例化,但是未完成属性赋值和相关的初始化的一个不完整的 bean 添加到三级缓存 singletonFactories 中
            * 具体内部会遍历后置处理器,判断是否有SmartInstantiationAwareBeanPostProcessor的实现类,然后调用里面getEarlyBeanReference覆盖当前Bean
            * 默认不做任何操作返回当前Bean,作为拓展,这里比如可以供AOP来创建代理类
            */

            this.addSingletonFactory(beanName, () -> {
                return this.getEarlyBeanReference(beanName, mbd, bean);
            });
        }
        // 开始对Bean实例进行初始化  
        Object exposedObject = bean;

        try {
            //给普通实例Bean填充属性,比如Bean里面有属性带了@Autowired,就是给里面的属性赋值
            this.populateBean(beanName, mbd, instanceWrapper);
            //执行Bean的初始化的前置回调方法、初始化回调方法、初始化的后置回调方法,这里有个点需要知道,AOP代理的Bean大部分都是通过后置回调方法创建的
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);
        } catch (Throwable var18) {
            if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
                throw (BeanCreationException)var18;
            }

            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
        }
        //从一级或者二级缓存中获取Bean的实例,不从三级缓存中取
        if (earlySingletonExposure) {
            Object earlySingletonReference = this.getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
                    String[] dependentBeans = this.getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
                    String[] var12 = dependentBeans;
                    int var13 = dependentBeans.length;

                    for(int var14 = 0; var14 < var13; ++var14) {
                        String dependentBean = var12[var14];
                        if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }

                    if (!actualDependentBeans.isEmpty()) {
                        throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                    }
                }
            }
        }

        try {
            // 如果实现了Disposable接口,会在这里进行注册,最后在销毁的时候调用相应的destroy方法
            this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
            return exposedObject;
        } catch (BeanDefinitionValidationException var16) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
        }
    }

实例化Bean

面试官:讲一下SpringBean的生命周期对应的实现在AbstractAutowireCapableBeanFactory类的createBeanInstance方法中:

   protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        // 解析class
        Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
        //确保class不为空,并且访问权限为public
        if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
        } else {
            //配置的一种特殊的callback回调方法,通过这个callback创建bean
            Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
            if (instanceSupplier != null) {
                return this.obtainFromSupplier(instanceSupplier, beanName);
            } else if (mbd.getFactoryMethodName() != null) {
                //通过工厂方法创建
                return this.instantiateUsingFactoryMethod(beanName, mbd, args);
            } else {
                // 一个类可能有多个构造器,所以Spring得根据参数个数、类型确定需要调用的构造器
                // 在使用构造器创建实例后,Spring会将解析过后确定下来的构造器或工厂方法保存在缓存中,避免再次创建相同bean时再次解析
                boolean resolved = false;
                boolean autowireNecessary = false;
                if (args == null) {
                    synchronized(mbd.constructorArgumentLock) {
                        if (mbd.resolvedConstructorOrFactoryMethod != null) {
                            //已经解析过class的构造器
                            resolved = true;
                            autowireNecessary = mbd.constructorArgumentsResolved;
                        }
                    }
                }

                if (resolved) {
                    //已经解析过class的构造器,使用已经解析好的构造器,否则使用默认构造器instantiateBean
                    return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
                } else {
                    // 需要根据参数解析、确定构造函数
                    Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
                    // 解析的构造器为空 && 注入类型不为构造函数自动注入 && bean定义中无构造器参数 && 传入参数为空
                    if (ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)) {
                        // 获取最优的构造函数
                        ctors = mbd.getPreferredConstructors();
                        return ctors != null ? this.autowireConstructor(beanName, mbd, ctors, (Object[])null) : this.instantiateBean(beanName, mbd);
                    } else {
                        //构造函数自动注入
                        return this.autowireConstructor(beanName, mbd, ctors, args);
                    }
                }
            }
        }
    }

填充Bean

面试官:讲一下SpringBean的生命周期对应的实现在AbstractAutowireCapableBeanFactory类的populateBean方法中:

    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        if (bw == null) {
            if (mbd.hasPropertyValues()) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
            }
        } else {
            // 给InstantiationAwareBeanPostProcessors最后一次机会在属性注入前修改Bean的属性值
           // 具体通过调用postProcessAfterInstantiation方法,如果调用返回false,表示不必继续进行依赖注入,直接返回
            boolean continueWithPropertyPopulation = true;
            if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
                Iterator var5 = this.getBeanPostProcessors().iterator();

                while(var5.hasNext()) {
                    BeanPostProcessor bp = (BeanPostProcessor)var5.next();
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                        if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                            continueWithPropertyPopulation = false;
                            break;
                        }
                    }
                }
            }

            if (continueWithPropertyPopulation) {
               // pvs 是一个 MutablePropertyValues 实例,里面实现了PropertyValues接口,提供属性的读写操作实现,同时可以通过调用构造函数实现深拷贝
                PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
                int resolvedAutowireMode = mbd.getResolvedAutowireMode();
                // 根据bean的依赖注入方式:即是否标注有 @Autowired 注解或 autowire=“byType/byName” 的标签
                // 会遍历bean中的属性,根据类型或名称来完成相应的注入
                if (resolvedAutowireMode == 1 || resolvedAutowireMode == 2) {
                    // 深拷贝当前已有的配置
                    MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
                    
                    // 根据名称进行注入
                    if (resolvedAutowireMode == 1) {
                        this.autowireByName(beanName, mbd, bw, newPvs);
                    }
                    // 根据类型进行注入
                    if (resolvedAutowireMode == 2) {
                        this.autowireByType(beanName, mbd, bw, newPvs);
                    }
                    // 结合注入后的配置,覆盖当前配置
                    pvs = newPvs;
                }
                // 容器是否注册了InstantiationAwareBeanPostProcessor
                boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
                // 是否进行依赖检查
                boolean needsDepCheck = mbd.getDependencyCheck() != 0;
                // 过滤出所有需要进行依赖检查的属性编辑器
                PropertyDescriptor[] filteredPds = null;
                if (hasInstAwareBpps) {
                    if (pvs == null) {
                        pvs = mbd.getPropertyValues();
                    }

                    Iterator var10 = this.getBeanPostProcessors().iterator();

                    while(var10.hasNext()) {
                        BeanPostProcessor bp = (BeanPostProcessor)var10.next();
                        // 如果有相关的后置处理器,进行后置处理
                        if (bp instanceof InstantiationAwareBeanPostProcessor) {
                            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                            PropertyValues pvsToUse = ibp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
                            if (pvsToUse == null) {
                                if (filteredPds == null) {
                                    filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                                }

                                pvsToUse = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
                                if (pvsToUse == null) {
                                    return;
                                }
                            }

                            pvs = pvsToUse;
                        }
                    }
                }
                 // 检查是否满足相关依赖关系,对应的depends-on属性,需要确保所有依赖的Bean先完成初始化
                if (needsDepCheck) {
                    if (filteredPds == null) {
                        filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                    }

                    this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
                }

                if (pvs != null) {
                    // 将pvs上所有的属性填充到BeanWrapper对应的Bean实例中
                    this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
                }

            }
        }
    }

初始化Bean

面试官:讲一下SpringBean的生命周期对应的实现在AbstractAutowireCapableBeanFactory类的initializeBean方法中:

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
 // 对特殊的bean进行处理:实现了 Aware、BeanClassLoaderAware、BeanFactoryAware 的处理
 if (System.getSecurityManager() != null) {
  AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
   // 激活 Aware 方法
   invokeAwareMethods(beanName, bean);
   return null;
  }, getAccessControlContext());
 }
 else {
  invokeAwareMethods(beanName, bean);
 }

 Object wrappedBean = bean;
 if (mbd == null || !mbd.isSynthetic()) {
  // 调用了bean后处理器的方法
  // BeanPostProcessor 提供的方法,在bean初始化前调用,这时的 bean已完成了实例化和属性填充注入工作
  wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
 }

 try {
  // 激活自定义的init的方法
  invokeInitMethods(beanName, wrappedBean, mbd);
 }
 catch (Throwable ex) {
  throw new BeanCreationException(
    (mbd != null ? mbd.getResourceDescription() : null),
    beanName, "Invocation of init method failed", ex);
 }
 if (mbd == null || !mbd.isSynthetic()) {
  // 调用bean后处理器的方法
  // BeanPostProcessor 提供的方法,在bean初始化后调用,这时候的bean 已经创建完成了
  wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
 }
 return wrappedBean;
}

销毁Bean

在注册Bean销毁逻辑时,首先需要通过!mbd.isPrototype()保证该Bean不是原型Bean,因为Spring容器并不会缓存原型Bean,就没有销毁一说

接着通过requiresDestruction()判断该Bean是否需要销毁,对需要销毁的Bean通过适配器模式生成DisposableBeanAdapter对象,最后调用registerDisposableBean()将DisposableBeanAdapter对象放入disposableBeans缓存中,当Spring容器关闭的时候,可以直接从该缓存中取出销毁调用,调用它们的销毁方法

对应的实现在AbstractAutowireCapableBeanFactory类的registerDisposableBeanIfNecessary方法中:

    protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
        AccessControlContext acc = System.getSecurityManager() != null ? this.getAccessControlContext() : null;    
        // 当前 bean 的作用域不是 Prototype && requiresDestruction 返回 true
        if (!mbd.isPrototype() && this.requiresDestruction(bean, mbd)) {
            if (mbd.isSingleton()) {
                this.registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, this.getBeanPostProcessors(), acc));
            } else {
                Scope scope = (Scope)this.scopes.get(mbd.getScope());
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
                }

                scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, this.getBeanPostProcessors(), acc));
            }
        }

    }

获取Bean

面试官:讲一下SpringBean的生命周期对应的实现在AbstractBeanFactory类的doGetBean方法中:

//获取IoC容器中指定名称的Bean
   public Object getBean(String name) throws BeansException {
       //doGetBean才是真正向IoC容器获取被管理Bean的过程
       return doGetBean(name, null, null, false);
   }
   //获取IoC容器中指定名称和类型的Bean
   public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
       return doGetBean(name, requiredType, null, false);
   }
   //获取IoC容器中指定名称和参数的Bean
   public Object getBean(String name, Object... args) throws BeansException {
       return doGetBean(name, null, args, false);
   }
   //获取IoC容器中指定名称、类型和参数的Bean
   public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
   return doGetBean(name, requiredType, args, false);
   }
   //真正实现向IoC容器获取Bean的功能,也是触发依赖注入功能的地方
   @SuppressWarnings("unchecked")
   protected <T> T doGetBean(
           final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
           throws BeansException {
       //根据指定的名称获取被管理Bean的名称,剥离指定名称中对容器的相关依赖
       //如果指定的是别名,将别名转换为规范的Bean名称
       final String beanName = transformedBeanName(name);
       Object bean;
       //先从缓存中取是否已经有被创建过的单例类型的Bean,对于单例模式的Bean整个IoC容器中只创建一次,不需要重复创建
       Object sharedInstance = getSingleton(beanName);
       //IoC容器创建单例模式Bean实例对象
       if (sharedInstance != null && args == null) {
           if (logger.isDebugEnabled()) {
               //如果指定名称的Bean在容器中已有单态模式的Bean被创建,直接返回已经创建的Bean
               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的实例对象,主要是完成FactoryBean的相关处理
           //注意:BeanFactory是管理容器中Bean的工厂,而FactoryBean是
           //创建创建对象的工厂Bean,两者之间有区别
           bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
       }
       else {//若不存在该单例bean,则进入双亲委派实例化该对象的流程。
           //如果该beanName有对应的在初始化中的多例对象,则抛出异常。
           if (isPrototypeCurrentlyInCreation(beanName)) {
               throw new BeanCurrentlyInCreationException(beanName);
           }
           //对IoC容器中是否存在指定名称的BeanDefinition进行检查,首先检查是否
           //能在当前的BeanFactory中获取的所需要的Bean,如果不能则委托当前容器
           //的父级容器去查找,如果还是找不到则沿着容器的继承体系向父级容器查找
           BeanFactory parentBeanFactory = getParentBeanFactory();
           //当前容器的父级容器存在,且当前容器中不存在指定名称的Bean
           if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
               //解析指定Bean名称的原始名称
               String nameToLookup = originalBeanName(name);
               if (args != null) {
                   //委派父级容器根据指定名称和显式的参数查找
                   return (T) parentBeanFactory.getBean(nameToLookup, args);
               }
               else {
                   //委派父级容器根据指定名称和类型查找
                   return parentBeanFactory.getBean(nameToLookup, requiredType);
               }
           }
           //创建的Bean是否需要进行类型验证,一般不需要
           if (!typeCheckOnly) {
               //向容器标记指定的Bean已经被创建
               markBeanAsCreated(beanName);
           }
            //根据指定Bean名称获取其父级的Bean定义,主要解决Bean继承时子类
           //合并父类公共属性问题
           final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
           checkMergedBeanDefinition(mbd, beanName, args);
           //获取当前Bean所有依赖Bean的名称
           String[] dependsOn = mbd.getDependsOn();
           //如果当前Bean有依赖Bean
           if (dependsOn != null) {
               for (String dependsOnBean : dependsOn) {
                   //递归调用getBean方法,获取当前Bean的依赖Bean
                   getBean(dependsOnBean);
                   //把被依赖Bean注册给当前依赖的Bean
                   registerDependentBean(dependsOnBean, beanName);
               }
           }
           //创建单态模式Bean的实例对象
           if (mbd.isSingleton()) {
           //这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象
               sharedInstance = getSingleton(beanName, new ObjectFactory() {
                   public Object getObject() throws BeansException {
                       try {
                           //创建一个指定Bean实例对象,如果有父级继承,则合并子//类和父类的定义
                           return createBean(beanName, mbd, args);
                       }
                       catch (BeansException ex) {
                           //显式地从容器单态模式Bean缓存中清除实例对象
                           destroySingleton(beanName);
                           throw ex;
                       }
                   }
               });
               //获取给定Bean的实例对象
               bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
           }
           //IoC容器创建原型模式Bean实例对象
           else if (mbd.isPrototype()) {
               //原型模式(Prototype)是每次都会创建一个新的对象
               Object prototypeInstance = null;
               try {
                   //回调beforePrototypeCreation方法,默认的功能是注册当前创//建的原型对象
                   beforePrototypeCreation(beanName);
                   //创建指定Bean对象实例
                   prototypeInstance = createBean(beanName, mbd, args);
               }
               finally {
                   //回调afterPrototypeCreation方法,默认的功能告诉IoC容器指//定Bean的原型对象不再创建了
                   afterPrototypeCreation(beanName);
               }
               //获取给定Bean的实例对象
               bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
           }
           //要创建的Bean既不是单态模式,也不是原型模式,则根据Bean定义资源中
           //配置的生命周期范围,选择实例化Bean的合适方法,这种在Web应用程序中
           //比较常用,如:request、session、application等生命周期
           else {
               String scopeName = mbd.getScope();
               final Scope scope = this.scopes.get(scopeName);
               //Bean定义资源中没有配置生命周期范围,则Bean定义不合法
               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的实例对象
                   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实例对象进行类型检查
       if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
           throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
       }
       return (T) bean;
   }

总结

面试官:讲一下SpringBean的生命周期

(1)BeanFactoryPostProcessor的postProcessorBeanFactory()方法:若某个IoC容器内添加了实现了BeanFactoryPostProcessor接口的实现类Bean,那么在该容器中实例化任何其他Bean之前可以回调该Bean中的postPrcessorBeanFactory()方法来对Bean的配置元数据进行更改,比如从XML配置文件中获取到的配置信息。

(2)Bean的实例化:Bean的实例化是使用反射实现的。

(3)Bean属性注入:Bean实例化完成后,利用反射技术实现属性及依赖Bean的注入。

(4)BeanNameAware的setBeanName()方法:如果某个Bean实现了BeanNameAware接口,那么Spring将会将Bean实例的ID传递给setBeanName()方法,在Bean类中新增一个beanName字段,并实现setBeanName()方法。

(5)BeanFactoryAware的setBeanFactory()方法:如果某个Bean实现了BeanFactoryAware接口,那么Spring将会将创建Bean的BeanFactory传递给setBeanFactory()方法,在Bean类中新增了一个beanFactory字段用来保存BeanFactory的值,并实现setBeanFactory()方法。

(6)ApplicationContextAware的setApplicationContext()方法:如果某个Bean实现了ApplicationContextAware接口,那么Spring将会将该Bean所在的上下文环境ApplicationContext传递给setApplicationContext()方法,在Bean类中新增一个ApplicationContext字段用来保存ApplicationContext的值,并实现setApplicationContext()方法。

(7)BeanPostProcessor预初始化方法:如果某个IoC容器中增加的实现BeanPostProcessor接口的实现类Bean,那么在该容器中实例化Bean之后,执行初始化之前会调用BeanPostProcessor中的postProcessBeforeInitialization()方法执行预初始化处理。

(8)InitializingBean的afterPropertiesSet()方法:如果Bean实现了InitializingBean接口,那么Bean在实例化完成后将会执行接口中的afterPropertiesSet()方法来进行初始化。

(9)自定义的inti-method指定的方法:如果配置文件中使用init-method属性指定了初始化方法,那么Bean在实例化完成后将会调用该属性指定的初始化方法进行Bean的初始化。

(10)BeanPostProcessor初始化后方法:如果某个IoC容器中增加的实现BeanPostProcessor接口的实现类Bean,那么在该容器中实例化Bean之后并且完成初始化调用后执行该接口中的postProcessorAfterInitialization()方法进行初始化后处理。

(11)使用Bean:此时有关Bean的所有准备工作均已完成,Bean可以被程序使用了,它们将会一直驻留在应用上下文中,直到该上下文环境被销毁。

(12)DisposableBean的destory()方法:如果Bean实现了DisposableBean接口,Spring将会在Bean实例销毁之前调用该接口的destory()方法,来完成一些销毁之前的处理工作。

(13)自定义的destory-method指定的方法:如果在配置文件中使用destory-method指定了销毁方法,那么在Bean实例销毁之前会调用该指定的方法完成一些销毁之前的处理工作。

注意:

1、BeanFactoryPostProcessor接口与BeanPostProcessor接口的作用范围是整个上下文环境中,使用方法是单独新增一个类来实现这些接口,那么在处理其他Bean的某些时刻就会回调响应的接口中的方法。

2、BeanNameAware、BeanFactoryAware、ApplicationContextAware的作用范围的Bean范围,即仅仅对实现了该接口的指定Bean有效,所有其使用方法是在要使用该功能的Bean自己来实现该接口。

3、第8点与第9点所述的两个初始化方法作用是一样的,我们完全可以使用其中的一种即可,一般情况我们使用第9点所述的方式,尽量少的去来Bean中实现某些接口,保持其独立性,低耦合性,尽量不要与Spring代码耦合在一起。第12和第13也是如此。

以上部分内容借鉴网络素材,如有不当,联系及时更正或删除

号外!号外!

如果这篇文章对你有所帮助,或者有所启发的话,帮忙点赞、在看、转发、收藏,你的支持就是我坚持下去的最大动力!

面试官:讲一下SpringBean的生命周期

分布式session共享问题

基于OAuth2.0实现第三方联合登录

spring多数据源事务不生效解决方法及源码分析

面试官:讲一下SpringBean的生命周期



原文始发于微信公众号(一安未来):面试官:讲一下SpringBean的生命周期

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/44641.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!