Spring单例Bean的生命周期(面试重点)

目录

1.实例化

2.属性赋值

3.初始化

4.使用

5.销毁


流程图:

1.实例化

对象的创建是bean生命周期的第一步。创建对象的方式有很多,比如 new反射clone等等spring中Bean创建的代码块如下:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
   // 再次解析BeanDefinition的class,确保class已经被解析
   Class<?> beanClass = resolveBeanClass(mbd, beanName);
 
   // 1: 如果提供了Supplier,通过Supplier产生对象
   Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
   if (instanceSupplier != null) {
      return obtainFromSupplier(instanceSupplier, beanName);
   }
 
   // 2: 如果有工厂方法,使用工厂方法产生对象
   // 在@Configration配置@Bean的方法,也会被解析为FactoryMethod
   if (mbd.getFactoryMethodName() != null) {
      return instantiateUsingFactoryMethod(beanName, mbd, args);
   }
   // 3: 推断构造方法
   // 3.1 执行后置处理器,获取候选构造方法
   Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
   // 3.2 需要自动注入的情况
   if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
         mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
      return autowireConstructor(beanName, mbd, ctors, args);
   }
 
   // 3.3 默认使用没有参数的构造方法
   return instantiateBean(beanName, mbd);
}

通过代码可以看出,实例化对象可以分为三个步骤:

1.先判断是否提供了Supplier,如果提供,则通过Supplier产生对象。

2.再判断是否提供工厂方法,如果提供,则使用工厂方法产生对象。

3.如果都没提供,需要进行构造方法的推断,逻辑为:

  • 如果没有,Spring默认选择无参构造方法;

  • 如果有,且有@Autowired(required=true)的构造方法,就会选择该构造方法;

    • 如果有,但是没有@Autowired(required=true)的构造方法,Spring会从所有加了@Autowired的构造方法中,根据构造器参数个数、类型匹配程度等综合打分,选择一个匹配参数最多,类型最准确的构造方法。

    • 如果仅有一个构造方法,会直接使用该构造方法(如果构造方法有参数,会自动注入依赖参数)

    • 如果有多个构造参数,会判断有没有加了@Autowired注解的构造参数

2.属性赋值

本阶段完成了Spring的核心功能之一:依赖注入,包括自动注入@Autowired注入等。Spring会根据bean的注入模型,选择根据名称自动注入还是根据类型自动注入。然后调用InstantiationAwareBeanPostProcessor#postProcessProperties()完成@Autowired和@Resource的属性注入。

以下是InstantiationAwareBeanPostProcessor#postProcessProperties()方法

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    
   // 获取bean的注入类型
   int resolvedAutowireMode = mbd.getResolvedAutowireMode();
   // 1: 自动注入
   if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
      MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
      // Add property values based on autowire by name if applicable.
      if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
         // 根据名称注入
         autowireByName(beanName, mbd, bw, newPvs);
      }
      // Add property values based on autowire by type if applicable.
      if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
         // 根据类型注入
         autowireByType(beanName, mbd, bw, newPvs);
      }
      pvs = newPvs;
   }
 
 
   // 2: 调用BeanPostProcessor,完成@Autowired @Resource属性填充
   PropertyDescriptor[] filteredPds = null;
   if (hasInstAwareBpps) {
      if (pvs == null) {
         pvs = mbd.getPropertyValues();
      }
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
 
            // 重点: 完成@Autowired @Resource属性填充
            PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
               if (filteredPds == null) {
                  // 需要注入的属性,会过滤掉Aware接口包含的属性(通过ignoreDependencyInterface添加)
                  filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
               }
               pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
               if (pvsToUse == null) {
                  return;
               }
            }
            pvs = pvsToUse;
         }
      }
   }
  
    // 3: 依赖检查
   if (needsDepCheck) {
      if (filteredPds == null) {
         filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
      }
      checkDependencies(beanName, mbd, filteredPds, pvs);
   }
   // 4: 将属性应用到bean中
   if (pvs != null) {
      applyPropertyValues(beanName, mbd, bw, pvs);
   }
}


3.初始化

在这一阶段主要做bean的初始化操作,包括:回调Aware接口回调初始化方法生成代理对象等。

  • invokeAwareMethods():回调BeanNameAware、BeanClassLoaderAware、BeanFactoryAware感知接口。

  • 回调后置处理器的前置方法,其中:

    • ApplicationContextAwareProcessor: 回调EnvironmentAware、ResourceLoaderAware、ApplicationContextAwareApplicationEventPublisherAware、MessageSourceAware、EmbeddedValueResolverAware感知接口。

    • InitDestroyAnnotationBeanPostProcessor:调用了标注了@PostConstruct的方法。

  • invokeInitMethods()调用初始化方法:

    • 如果bean是InitializingBean的子类, 先调用afterPropertiesSet()

    • 回调自定义的initMethod,比如通过@Bean(initMethod = "xxx")指定的初始化方法。

  • 回调后置处理器的后置方法,可能返回代理对象。其中AbstractAutoProxyCreator和 AbstractAdvisingBeanPostProcessor都有可能产生代理对象,比如InfrastructureAdvisorAutoProxyCreator完成了@Transactional代理对象的生成,AsyncAnnotationBeanPostProcessor完成了@Async代理对象的生成。

4.使用

在完成初始化之后,bean会被放到单例池中,并且可以被通过spring获取到。


5.销毁

在创建bean的时候,会判断如果bean是DisposableBeanAutoCloseable的子类,或者有 destroy-method等,会注册为可销毁的bean,在容器关闭时,调用对应的方法进行bean的销毁。

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {
   try {
      // 为bean注册DisposableBean,在容器关闭时,调用destory()
      registerDisposableBeanIfNecessary(beanName, bean, mbd);
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
   }
 
   return exposedObject;
}

总结

  Spring单例Bean的生命周期主要包括五个阶段:首先是实例化,通过各种方式如反射或工厂方法创建Bean实例;其次是属性赋值,进行依赖注入,包括自动注入和@Autowired注解的属性注入;接着是初始化,涉及Aware接口的回调、初始化方法的调用以及可能的代理对象生成;随后Bean被使用,放入单例池中供应用程序使用;最后是销毁阶段,如果Bean实现了特定的接口或配置了销毁方法,Spring容器关闭时会调用这些方法以释放资源。这个生命周期允许开发者在Bean的各个阶段进行自定义处理,以满足特定的业务需求。

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值