搞懂Spring Bean的一生,这篇文章就够了

本文深入探讨了Spring Bean从初始化到销毁的整个生命周期,包括基本概念、容器启动流程、BeanDefinition解析、Bean生命周期的各个阶段,如实例化、初始化、销毁等。文中详细解释了BeanFactoryPostProcessor和BeanPostProcessor在Bean生命周期中的关键作用,以及如何通过实现这些接口对Spring进行扩展。通过了解这些,读者可以更好地理解Spring Bean的工作原理。
摘要由CSDN通过智能技术生成

基本概念

「Spring是一个IOC容器」

当我们不用Spring进行开发时,我们需要在代码中设置对象的依赖关系。当我们用了Spring之后,由Spring来管理这种依赖关系,当我们想使用对象时,直接从Spring容器中获取即可

「BeanDefinition」

在Spring中对象被叫做Bean,因为Spring Bean在Java类的基础上增加了很多概念,比如scope(作用域),isLazyInit(是否延迟初始化),isSingleton(是否单例),此时Java类不能完整的描述,所以需要新的定义描述类,这个类就是BeanDefinition

「BeanDefinitionReader」

BeanDefinitionReader会将配置的bean解析成为BeanDefinition,Spring Bean的配置方式有很多种,如XML,properties,groovy,注解(可能通过properties,groovy的方式你不常用,但Spring确实支持这种方式),所以BeanDefinitionReader的实现类也很多

2w字搞懂Spring Bean的一生

「ClassPathBeanDefinitionScanner」当把Bean配置出后,得需要相应的组件把他们从资源文件中扫描出来吗,这个组件就是ClassPathBeanDefinitionScanner

「BeanDefinitionRegistry」BeanDefinitionReader将配置的bean解析成为BeanDefinition,需要将BeanDefinition保存到BeanDefinitionRegistry。类似工厂把原料保存到仓库中,供后续生产产品使用

「BeanFactory」

BeanFactory会根据BeanDefinition将Bean生产出来,并保存下来

「DefaultListableBeanFactory」

DefaultListableBeanFactory在绝大多数的场景都是BeanFactory的实现类,DefaultListableBeanFactory实现了BeanDefinitionRegistry接口和BeanFactory接口,所以能保存Bean定义,同时又能根据Bean定义将Bean生产出来

「BeanPostProcessor」

BeanFactory根据BeanDefinition生成Bean的过程是一个标准化的流程,就像一个流水线一样,当然你可以在这个流水线上做一些自定义的操作。「在Spring中你可以通过实现BeanPostProcessor来干预Bean的生产过程」

「BeanFactoryPostProcessor」

Spring作为一个强大的容器,不仅能让你干预Bean的生产过程,还可以让你干预BeanFactory,「例如你可以通过BeanFactoryPostProcessor将Bean的作用域都该成原型,默认是单例」

Spring容器启动流程

容器初始化过程

我们常用的容器有如下2种

  1. 基于xml配置Bean(ClassPathXmlApplicationContext)
  2. 基于注解配置Bean(AnnotationConfigApplicationContext)

因为我们现在开发都是基于注解,所以分析一下AnnotationConfigApplicationContext的启动流程

@Repository
public class UserDao {

 public String getUser() {
  return "user";
 }
}
@Configuration
@ComponentScan("com.javashitang")
public class AppConfig {

}
public class Main {

 public static void main(String[] args) {
  // 容器启动完毕
  AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
  UserDao userDao = context.getBean(UserDao.class);
  String str = userDao.getUser();
  System.out.println(str);
 }
}

可以看到当AnnotationConfigApplicationContext被new出来的时候,容器已经启动完毕,后续就可以直接从容器中获取Bean了。

构造函数主要执行了如下3个步骤,其中this和register方法主要是容器初始化的过程。refresh是刷新容器,即启动的过程,在这个里面做了很多操作,我们后面会用一个小节来分析

2w字搞懂Spring Bean的一生

初始化的过程可以看到初始化beanFactory为DefaultListableBeanFactory。「这里可以看到AnnotationConfigApplicationContext虽然本身是一个beanFactory(实现了BeanFactory接口),但是依赖查找,依赖注入的过程是依赖内部的beanFactory来实现的(典型的代理模式)」

「另外需要注意的一点是,在容器初始化的过程中注册了6个Bean」

  1. ConfigurationClassPostProcessor(「实现了BeanFactoryPostProcessor,处理@Configuration,@ComponmentScan等注解,这是一个很重要的类」
  2. 「AutowiredAnnotationBeanPostProcessor(实现了BeanPostProcessor,处理@Autowired,@Value等)」
  3. 「CommonAnnotationBeanPostProcessor(实现了BeanPostProcessor,用来处理JSR-250规范的注解,如@Resource,@PostConstruct等)」
  4. PersistenceAnnotationBeanPostProcessor(实现了BeanFactoryPostProcessor,用来支持JPA,在我们这个Demo中不会注册,因为路径中没有JPA相关的类)
  5. EventListenerMethodProcessor(实现了BeanFactoryPostProcessor)
  6. DefaultEventListenerFactory

注册的过程估计你也猜到了,就是将对应的类,如ConfigurationClassPostProcessor解析为RootBeanDefinition,并注册到BeanDefinitionRegistry中

「这几个BeanPostProcessor在Spring Bean的生命周期中发挥了很大的作用,我们在Spring Bean生命周期这篇文章中来分析」

「好了,我们来看最重要的过程,容器刷新的过程,入口方法为AbstractApplicationContext#refresh」

容器刷新过程

「容器刷新的过程可以细分为如下几个步骤」

  1. Spring应用上下文启动准备阶段
  2. BeanFactory创建阶段
  3. BeanFactory准备阶段
  4. BeanFactory后置处理阶段
  5. BeanFactory注册BeanPostProcessor阶段
  6. 初始化内建Bean:MessageSource
  7. 初始化内建Bean:Spring事件广播器
  8. Spring应用上下文刷新阶段
  9. Spring事件监听器注册阶段
  10. BeanFactory初始化完成阶段
  11. Spring应用上下文启动完成阶段

2w字搞懂Spring Bean的一生

Spring应用上下文启动准备阶段

AbstractApplicationContext#prepareRefresh

  1. 记录启动时间 startupDate
  2. 设置标志为closed(false),active(true)
  3. 初始化PropertySources
  4. 校验Environment中必须属性
  5. 初始化事件监听器集合
  6. 初始化早期Spring事件集合

BeanFactory创建阶段

AbstractApplicationContext#obtainFreshBeanFactory

刷新Spring应用上下文底层BeanFactory(refreshBeanFactory)

  1. 如果已存在BeanFactory,销毁Bean,并且关闭BeanFactory
  2. 创建DefaultListableBeanFactory(一般情况下都是DefaultListableBeanFactory)
  3. 设置BeanFactor
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值