Spring学习 - Bean生命周期

背景

谈到Spring,最先想到的自然是SpringFrameWork,即Spring框架。而框架最为核心的内容,其实就是一个Bean容器。基于该容器之上,才有了context、aop、web等等其它模块的内容,所以搞清楚Bean容器的工作流程是非常有必要的。因此本文将结合自身的学习和理解,来谈一谈spring容器中Bean完整的生命周期是怎样的。

1. 创建前准备

1.1 BeanDefinition解析流程

在了解Bean的创建工作之前,我们需要先了解一下BeanDefinition。在spring容器中,对象的创建工作可分为两个阶段

1.对象实例化:也就是我们通常说的new一个对象(但在容器中,是通过反射来进行实例化)。

2.对象初始化:完成对象属性填充,执行Aware接口需要实现的方法,以及初始化、后置处理工作等。

 

因此,大家需要思考一个问题:

无论是实例化还是初始化阶段,spring容器都会需要使用到这些bean的信息,如成员属性、构造方法、类的全限定名称等等。因此这一系列信息在容器创建工作开始之前,spring容器将这些信息通通解析封装成了BeanDefinition(见名知意,类的定义信息),即一个bean对应一个BeanDefinition

也就是说,无论是通过xml文件配置bean,还是通过注解扫描的方式注入的Bean,都会首先被解析成一个BeanDefinition对象。而这里的解析工作都是由一个叫BeanDefinitionReader的接口完成。

综上,springbean创建前的解析流程大致如图:

1.2 BeanFactoryPostProcessor

在上一步骤获取到BeanDefinition对象之后,似乎看起来已经可以开始创建了,但是出于优秀的扩展性,spring的context模块在初始化容器时(传说中的refresh()方法),会执行一系列BeanFactorryPostProcessor的实现类。

如在xml文件中配置的数据源:<property name="jdbcUrl" value="${jdbc.url}" /> 

就是在这里将${jdbc.url}解析成配置文件里的值jdbc:mysql://localhost:3306/xxx

2. 对象实例化

在得到beanName对应得BeanDefinition对象后,自然就能拿到bean的class对象,是的,一切都是那么的丝滑。

然后一顿反射

Constructor ctor = clazz.getDeclareContructor();

stor.newInstance();

是的,对象就这么出来了。

3. 对象初始化

看似对象已经创建完成了,其实故事这才开始。

在完成实例化阶段后,容器拿到的对象只是实例化,但未初始化的对象,因此我们可以称它为“半成品对象”。基于该半成品对象,还有以下一系列流程。

3.1 属性注入

属性注入,也就是我们常说的DI(依赖注入)。对应到源码中,就是这个方法:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

该步骤处理的内容,就是将bean所依赖的成员属性注入(setter)到对象里;如果注入的成员属性是个引用类型的对象,那么容器会进行递归创建该成员属性(实例化、初始化)。

// 省略getter、setter
public class A {
    private class B;
}

public class B {
    private class A;
}

那个熟悉的循环依赖问题就是在这里处理的(通过三级缓存)。

3.2 执行Aware接口实现类

所谓Aware接口,具体是干啥的呢?具体咱们可以参考上图BeanFactory源码里的一段注释,作用应该可以感受到了。也就是若某个Bean实现了某种Aware接口,那么在初始化阶段的这个位置,就会去执行对应的Aware接口的实现方法,通过该方法可以获得对应的属性。如BeanNameAware,那么通过该方法可以获取BeanName,再如BeanFactoryAware,通过该方法久可以获取BeanFactory。

从图种可以看到,这里有很多种Aware,但是在此阶段,只会执行三种:BeanNameAware、BeanClassLoaderAware、BeanFactoryAware,如图:

3.3 bean后置处理

bean的后置处理主要包含3个操作(其实就是上图initializeBean的内容):

1. 执行所有BeanPostProcessor实现类的postProcessBeforeInitialization()方法。

2. 依次执行InitializingBean的afterPropertiesSet()、自定义init()方法。有图为证...

3. 执行所有BeanPostProcessor实现类的postProcessAfterInitialization()方法。

方法到这,其实bean对象的创建工作(实例化、初始化)已经接近尾声,是一个完整对象了。但是,此处也是给aop模块留下了扩展入口。

aop对应的代理对象生成器AbstractAutoProxyCreator,其入口就是它的postProcessAfterInitialization()方法。

4. 总结

至此,springbean的对象创建已经完成。最后附上一张总体流程图(本人热衷抽象派)

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值