简单梳理下SpringBean生命周期


Sping的容器启动和Bean工厂的初始化相关后续整理。

1.BeanDefinition的生成

1.1 包路径扫描

1.通过ResourcePatternResolve扫描指定包路径下的所有.class文件。
2.每一个class文件在Spring中都抽象成Resource对象。

1.2 扫描解析Resource文件

1.利用MetadataReaderFactory解析Resource对象得到MetadatarReader对象。
2.解析过程采用的是ASM字节码技术,没有加载类。

1.3 MetadataReader筛选

1.MetadataReader拥有类的所有信息,通过判断类上是否带有@Conditional注解来筛选。
2.如果类上有条件注解,或者有excludeFilters等过滤表达式,则匹配的类就直接抛弃。

1.4 BeanDefinition的创建

1.如果筛选通过,那么这个class就是一个需要被Spring管理。
2.MetadataReader生成这个类的ScannedGenericBeanDefinition并加入BeanDefinition集合。

2.BeanDefinition的合并

BeanDefinition存在父子关系,BeanDefinition可以继承其它的BeanDefinition,那么此时就会创建新的BeanDefinition,将父子BeanDefinition合并。

3.类加载

当一个类有了自己的BeanDefinition,那么就可以基于BeanDefinition生成SpringBean了,在创建对象之前肯定需要类加载,因为包扫描的时候是基于ASM字节码技术。
1.AbstractAutowireCapableBeanFactory # createBean( )方法执行。
2.首先获取BeanFactory设置的类加载器,如果没有设置则使用默认的类加载器。
3.默认的类加载器调用ClassUtils.getDefaultClassLoader( )返回。
4.这个工具类优先返回当前线程上下文的ClassLoader。
5.如果当前线程上下文没有设置类加载器,则返回ClassUtils这个类的类加载器。
6.如果ClassUtils的类加载器为空(一般不会有这种情况,除非把这个类移到rt.jar包下交给BootStrap加载 器),则说明这类是BootStrapClassLoader。

4.实例化前

在实例化创建对象之前,Spring提供了拓展点,基于postProcessor机制来做一些前后操作。
InstantiationAwareBeanPostProcessor # postProcessBeforeInstantiation( )方法会被执行,每个SpringBean实例化前都会执行它(这个拓展点写死在Spring源码中)。
这个方法的入参是实例化这个对象的Class对象和BeanName,返回值是Object,当然也可以返回null。如果自己new了一个这个类的对象,那么当前实例化的Bean就不会依赖注入等操作,直接快进到初始化后的流程。

5.实例化

5.1 工厂方法创建对象

根据BeanDefinition的描述创建对象。
1.如果BeanDefinition的factoryMethod属性有值,则调用这个属性值的工厂方法来创建对象。
2.如果BeanDefinition的supplier属性有值,则调用Supplier#get( )方法返回对象。

5.2 构造方法的推断

如果该类没有写构造方法,那么Spring就是用无参构造。如果这个类有多个构造,并且没有加类似@Autowired的注解来指定用哪个构造,那么Spring会进行构造推断过程:
1.如果类只有1个构造方法,Spirng就调用这个构造。
2.如果类存在多个构造,且未指定,那么Spring判断这几个构造里是否有无参构造,如果有则调用。如果没有,Spring就会抛异常。

6.BeanDefinition的后置处理

当Bean对象实例化创建出来以后,就可以给对象的属性赋值。在赋值之前,会基于postProcessor机制对BeanDefdition进行拓展。
MergedBeanDefinitionPostProcessor # postProcessMergedBeanDefinition()这个方法会被调用,入参有BeanDefinition,可以对BeanDefinition进行操作。

7.实例化后

实例化前类似,基于postProcessor机制的拓展功能,在Bean对象实例化后也有后置处理器。
InstantiationAwareBeanPostPorcessor # postProcessAfterInstantiation()方法被执行,入参就是实例化后的Bean对象和BeanName,可以对Bean对象进行额外的自定义操作。不过这个拓展点Spring内部没有使用。

8.属性注入

对@Autowired、@Resource、@Value等注解的处理,底层基于postProcessor机制完成。

9.各种基础Aware接口的回调

  - BeanNameAware
  - BeanClassLoaderAware
  - BeanFactoryAware等

10.初始化前

1.(重点)基于BeanPostProcessor # postProcessBeforeInitialization()拓展机制进行 初始化前的业务自定义处理,入参是已经有属性的Bean,返回值也是这个Bean。
2.@PostConstruct的执行
3.ApplicationContextAwareProcessor执行其它Aware的回调:

     - ResourceLoaderWare
     - MessageSourceAware
     - ApplicationEventPublisherAware等

11.初始化

  - 检查该类是否实现了InitializingBean接口,如果实现了,就调用afterPropertiesSet( )。
  - 执行BeanDefinition中指定的init-method初始化方法。

12.初始化后

基于BeanPostProcessor # postProcessAfterInitialization()拓展机制调用,实现自定义的操作,入参和返回值都是当前Bean。
Spring的AOP操作也是基于初始化后postProcessor实现的。

Bean的销毁

当容器调用close( )方法时,Spring容器就会进行关闭的流程。在Bean对象初始化后阶段,Spring
会检查该Bean是否实现了DisposableBean接口或者实现了AutoCloseable接口或者BeanDefinition中指定了destroyMethod方法、有@PreDestroy注解。
如果符合其中之一,就把Bean封装成一个DisposableBeanAdapter对象,存入DisposableBeans这个Map中,以备后续关闭的时候使用。
在容器销毁的时候:

  1. spring发布ContextClosedEvent事件
  2. onClose( )方法被触发
  3. 遍历DisposableBeans这个Map,挨个儿从单例池中移除,调用Bean的销毁方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Minor王智

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值