IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Spring bean核心生命周期 -> 正文阅读

[Java知识库]Spring bean核心生命周期

Spring bean生命周期

前言

在Spring 框架中,代码定义的对象统一由Spring 容器管理,由Spring容器来创建,初始化。

那么一个bean的简版生命周期如下图:

图一

实例化一个bean对象,完成属性注入,执行初始化方法,此时bean可以被我们所使用,最后销毁。

Spring也赋予了一个bean在上述4个阶段中做一些增强的操作,下文详细分析。

Spring bean生命周期

Spring bean详细生命周期流程图:

图二

从doCreateBean() 方法开始

AbstractAutowireCapableBeanFactory抽象类:

省略部分代码
protected?Object?doCreateBean(String?beanName,?RootBeanDefinition?mbd,?@Nullable?Object[]?args)
???throws?BeanCreationException?{

??//?Instantiate?the?bean.
??BeanWrapper?instanceWrapper?=?null;
??if?(mbd.isSingleton())?{
???instanceWrapper?=?this.factoryBeanInstanceCache.remove(beanName);
??}
??if?(instanceWrapper?==?null)?{
??????//实例化
???instanceWrapper?=?createBeanInstance(beanName,?mbd,?args);
??}
??Object?bean?=?instanceWrapper.getWrappedInstance();

??//?Initialize?the?bean?instance.
??Object?exposedObject?=?bean;
????//属性填充
????populateBean(beanName,?mbd,?instanceWrapper);
????//初始化bean实例
????exposedObject?=?initializeBean(beanName,?exposedObject,?mbd);

??return?exposedObject;
?}

在doCreateBean()方法中:

  • 调用createBeanInstance() 方法完成对象实例化。

  • 调用populateBean() 方法填充属性。

  • 调用initializeBean() 方法完成bean实例的初始化方法回调。

initializeBean()方法

AbstractAutowireCapableBeanFactory抽象类:

protected?Object?initializeBean(String?beanName,?Object?bean,?@Nullable?RootBeanDefinition?mbd)?{
??if?(System.getSecurityManager()?!=?null)?{
???AccessController.doPrivileged((PrivilegedAction<Object>)?()?->?{
????invokeAwareMethods(beanName,?bean);
????return?null;
???},?getAccessControlContext());
??}
??else?{
??????//调用感知方法
???invokeAwareMethods(beanName,?bean);
??}

??Object?wrappedBean?=?bean;
??if?(mbd?==?null?||?!mbd.isSynthetic())?{
??????//初始化前调用bean后置处理器
???wrappedBean?=?applyBeanPostProcessorsBeforeInitialization(wrappedBean,?beanName);
??}

??try?{
??????//调用初始化方法
???invokeInitMethods(beanName,?wrappedBean,?mbd);
??}
??catch?(Throwable?ex)?{
???throw?new?BeanCreationException(
?????(mbd?!=?null???mbd.getResourceDescription()?:?null),
?????beanName,?"Invocation?of?init?method?failed",?ex);
??}
??if?(mbd?==?null?||?!mbd.isSynthetic())?{
??????//初始化后调用bean后置处理器
???wrappedBean?=?applyBeanPostProcessorsAfterInitialization(wrappedBean,?beanName);
??}

??return?wrappedBean;
?}

在initializeBean()方法中:

  • 调用invokeAwareMethods() 方法完成相关属性的注入。

  • 初始化前调用bean后置处理器。

  • 调用invokeInitMethods() 方法完成InitializingBean接口的回调。

  • 初始化后调用bean后置处理器。

invokeAwareMethods() 方法注入相关属性

private?void?invokeAwareMethods(String?beanName,?Object?bean)?{
??if?(bean?instanceof?Aware)?{
???if?(bean?instanceof?BeanNameAware)?{
????((BeanNameAware)?bean).setBeanName(beanName);
???}
???if?(bean?instanceof?BeanClassLoaderAware)?{
????ClassLoader?bcl?=?getBeanClassLoader();
????if?(bcl?!=?null)?{
?????((BeanClassLoaderAware)?bean).setBeanClassLoader(bcl);
????}
???}
???if?(bean?instanceof?BeanFactoryAware)?{
????((BeanFactoryAware)?bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
???}
??}
?}

applyBeanPostProcessorsBeforeInitialization()
applyBeanPostProcessorsAfterInitialization()
方法中会获取bean后置处理器集合,依次执行:

  • ApplicationContextAwareProcessor 后置处理器:用于注入应用上下文属性。

  • InitDestroyAnnotationBeanPostProcessor 后置处理器:会找出@PostConstruct、@PreDestroy修饰的方法并执行。

自定义init方法

图二中调用自定义init方法invokeCustomInitMethod() 是指:

  • 在xml配置bean时通过init-method标签指定。

  • 或者通过注解@Bean(initMethod = "xxx")指定,默认为空。

验证

@Component
@Slf4j
@Scope(value?=?"prototype")
@PropertySource({"classpath:bootstrap.yml"})
public?class?FullBean?implements?BeanNameAware,?BeanFactoryAware,?ApplicationContextAware,?InitializingBean,
????????InstantiationAwareBeanPostProcessor,
????????BeanPostProcessor,
????????DisposableBean?{

????private?String?name;

????public?FullBean()?{
????????log.info("无参构造方法:?{}",?this);
????}

????@Value("${name}")
????public?void?setName(String?name)?{
????????log.info("setName:?{}",?name);
????????this.name?=?name;
????}

????@Override
????public?void?setBeanName(String?name)?{
????????log.info("beanName:?{}",?name);
????}
????
????@Override
????public?void?setBeanFactory(BeanFactory?beanFactory)?throws?BeansException?{
????????log.info("beanFactory:?{}",?beanFactory.getClass());
????}

????@Override
????public?void?setApplicationContext(ApplicationContext?applicationContext)?throws?BeansException?{
????????log.info("applicationContext:?{}",?applicationContext.getId());
????}

????@PostConstruct
????public?void?postConstruct()?{
????????log.info("postConstruct执行");
????}

????@Override
????public?void?afterPropertiesSet()?throws?Exception?{
????????log.info("afterPropertiesSet执行");
????}

????@Override
????public?Object?postProcessBeforeInstantiation(Class<?>?beanClass,?String?beanName)?throws?BeansException?{
????????log.info("实例化前:?{}",?beanName);
????????return?null;
????}

????@Override
????public?boolean?postProcessAfterInstantiation(Object?bean,?String?beanName)?throws?BeansException?{
????????log.info("实例化后:?{}",?beanName);
????????return?true;
????}

????@Override
????public?PropertyValues?postProcessProperties(PropertyValues?pvs,?Object?bean,?String?beanName)?throws?BeansException?{
????????log.info("后处理属性注入:?{}",?beanName);
????????return?null;
????}

????@Override
????public?PropertyValues?postProcessPropertyValues(PropertyValues?pvs,?PropertyDescriptor[]?pds,?Object?bean,?String?beanName)?throws?BeansException?{
????????log.info("属性注入:?{}",?beanName);
????????return?pvs;
????}

????@Override
????public?Object?postProcessBeforeInitialization(Object?bean,?String?beanName)?throws?BeansException?{
????????log.info("初始化前:?{}",?beanName);
????????return?bean;
????}

????@Override
????public?Object?postProcessAfterInitialization(Object?bean,?String?beanName)?throws?BeansException?{
????????log.info("初始化后:?{}",?beanName);
????????return?bean;
????}

????@Override
????public?void?destroy()?throws?Exception?{
????????log.info("bean销毁");
????}
}

执行结果:

实现BeanPostProcessor接口不生效原因

单例模式下:

bean作用域默认为单例,也可以在bean上加 @Scope(value = "singleton")。 此时FullBean类中不会执行BeanPostProcessor接口覆盖的方法。

原因:

AbstractApplicationContext#refresh() -> registerBeanPostProcessors() 方法中,FullBean由于实现了BeanPostProcessor接口,会被提前初始化,此时FullBean还未注册到BeanPostProcessor集合中。

refresh()方法分析见:Spring boot启动流程分析精简版

registerBeanPostProcessors() 方法会调用 PostProcessorRegistrationDelegate#registerBeanPostProcessors()

由于fullBean 是一个后置处理器类,那么此时fullBean 会先被创建,并放入单例缓存池中(缓存在DefaultSingletonBeanRegistry 类的singletonObjects 属性 map集合中),接着会将此bean注册到BeanPostProcessor 集合中。所以在单例情况下,实现了BeanPostProcessor 接口后,不会执行其实现的方法。

后面 getBean("fullBean") 直接从缓存中获取bean 实例。

原型模式下:

在类上注解@Scope(value = "prototype") 设置此bean作用域为原型模式。容器启动时由于fullBean 是后置处理器类,也不会执行。

Spring 应用容器启动完毕后,下一次getBean("fullBean") 时,会再次创建bean对象,此时会执行其后置处理器覆盖的方法。

小结

本文分析了核心的关键流程,旨在了解bean 的生命周期。建议对照图二的流程图,去debug 源码会更加清晰。

注:类初始化和bean生命周期中的初始化不是一个概念

  • 类初始化:Class.forName() 过程叫类初始化,会执行static block。返回一个class对象的引用。

  • 文中bean初始化:执行对应的初始化方法。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-05-08 07:54:27  更:2022-05-08 07:56:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:27:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码