【年后跳槽必看篇 - 非广告】Spring Bean 的生命周期
既然聊到 Spring Bean 的生命周期。首先,我们要知道的是 Java Bean 和 Spring Bean 实例化过程是有一些区别的。
Java Bean 创建的步骤
简要的说一下普通环境下创建 Java Bean 简要的几个步骤:
首先 Java 源码会被编译为 class 文件。
接着类被初始化(比如 new 对象、反射获取对象等操作)。
然后 class 文件会被虚拟机通过类加载器加载到 JVM。
最后会初始化对象供我们使用。
简单来说可以理解为 Class 文件作为【模板】进而创建出具体的实例。面试这么简单聊一下从而引出 Spring 对象的生命周期,显得你更加从容。手动狗头。哈哈
补充:Java 对象的创建过程详细可参考文章:
步入正题 :
Spring Bean 的生命周期
而 Spring 所管理的 Bean 与 Java 不同的是,除了 Class 对象之外,还会使用 BeanDefinition 的实例来描述对象的信息。比如说:
我们可以在 Spring 所管理的 Bean 中有一系列的描述,常见的有:@Scope、@Lazy、@DependsOn 等等 。
可以理解为:Class 只描述了类的信息,而 BeanDefinition 描述了对象的信息。也就是 Spring 有 BeanDefinition 来存储我们日常给 Spring Bean 定义的元数据(@Scope、@Lazy、@DependsOn)。
流程
首先 Spring 在启动的时候需要扫描在 XML/注解/JavaConfig 中需要被 Spring 管理的 Bean 信息
随后,会将这些信息封装成 BeanDefinition,最后会把这些信息放到一个 BeanDefinitionMap 中
BeanDefinitionMap 中的 key 是 beanName,value 是 BeanDefinition 对象
到这里其实是把定义的元数据加载起来,目前真实的对象还没有进行实例化
接着会遍历这个 BeanDefinitionMap,执行 BeanFactoryPostProcessor 这个 Bean 工厂后置处理的逻辑
比如说:我们平时定义的占位符信息,就是通过 BeanFactoryPostProcessor 的子类 PropertyPlaceholderConfigurer 进行注入进去的。
当然这里我们也可以通过自定义 BeanFactoryPostProcessor 来对我们定义好的 Bean 元数据进行获取或者修改。只是我们一般不会这么做的,实际的应用场景也很少。
BeanFactoryPostProcessor 后置处理器执行完之后,就到了实例化对象了,在 Spring 里边是通过反射来实现的,一般情况下会通过反射选择合适的构造器来把对象实例化。注意,这里把对象实例化,只是将对象创建出来,而对象的属性还没有注入的。
比如:有一个对象 UserService 依赖着 SendService 对象,这时 SendService 还是 null 的。
实例化完成后,紧接着就是把对象的相关属性给注入。
属性注入完成之后,就是初始化的动作了。
Bean 的初始化首先会判断该 Bean 时候实现了 Aware 相关的接口,如果存在了则会填充相关资源。
比如:我在系统中系统通过代码程序的方式获得指定的 Spring Bean。我就会抽取一个工具类,去实现 ApplicationContextAware 接口,来获取 ApplicationContext 对象从而获取 Spring Bean。
Aware 相关的接口处理完之后,就回到 BeanPostProcessor 后置处理器了,BeanPostProcessor 后置处理器有两个方法,一个是 before,一个是 after。
这个 Bean Post Processor 后置处理器是 AOP 实现的关键。关键子类 AnnotationAwareAspectJAutoProxyCreator。
所以,执行完 Aware 相关的接口就会执行 BeanPostProcessor 相关子类的 Before 方法
BeanPostProcessor 相关子类的 before 方法执行完成之后,则会执行 init 相关的方法。
比如:@PostConstruct 、以及实现了 InitizlizingBean 接口、定义的 init-method 方法
它们的执行顺序为:@PostConstruct 、实现了 InitizlizingBean 的接口、定义的 init-method 方法
实际场景中 @PostConstruct 经常用在对象实例化后,我们要初始化爱你公关工作或者启动个线程去 MQ 拉取数据
等到 int 方法执行完成之后,就会执行 BeanPostProcessor 的 after 方法。
基本的重要流程就已经走完了,此后我们便可以获取对象去使用了。
最后销毁的时候就看有没有配置相关的 destroy 方法,执行就完事了。
上述整体流程大致如图所示:
至此:Spring Bean 的一整套生命周期也就完事了。
相信你这么吹嘘一番相比是可以 hold 住面试官的了。
补充:
关于 Spring Bean 生命周期具体源码流程可阅读以下文章:
Spring 源码阅读的系列文章
如有问题,欢迎加微信交流:w714771310,备注- 技术交流 。或关注微信公众号【码上遇见你】。
希望对你有所帮助,祝你学习顺利
版权声明: 本文为 InfoQ 作者【派大星】的原创文章。
原文链接:【http://xie.infoq.cn/article/f2847360c52476063693ab421】。
本文遵守【CC BY-NC-ND】协议,转载请保留原文出处及本版权声明。
评论