当前位置: 首页 > news >正文

spring boot bean的生命周期

spring boot bean的生命周期

  • Bean创建和销毁过程中调用的顺序
    • Bean创建过程方法调用顺序
    • Bean销毁过程方法调用顺序
    • BeanPostProcessor
      • BeanPostProcessor内部执行顺序
      • `BeanPostProcessor`子类及其调用顺序相关因素
  • bean的扩展点
    • ApplicationContextAware
    • ApplicationContextInitializer
      • mian函数中添加
      • 配置文件中配置 application.properties
      • SpringBoot的SPI扩展---META-INF/spring.factories中配置
    • BeanPostProcessor
      • 例子:简单地打印了Bean的名字
    • InitializingBean
      • 构造一个bean的执行顺序
    • 常见的Aware接口

Bean创建和销毁过程中调用的顺序

在实际应用中,通常
不会同时使用@PostConstruct和InitializingBean#afterPropertiesSet(),
也不会同时使用@PreDestroy和DisposableBean#destroy(),
因为它们是重复的机制。
此外,还需要注意的是,Aware接口的方法调用通常发生在依赖注入之后,但在@PostConstruct之前。这是因为Aware接口提供的方法允许Bean访问其在Spring容器中的环境和配置信息,这可能需要依赖项已经被注入。

Bean创建过程方法调用顺序

调用顺序方法/注解描述
1构造方法通过调用Bean的构造方法来创建Bean对象
2@Autowired用于自动装配Bean的依赖项,通常在构造方法之后立即发生
3Aware接口方法如果Bean实现了Aware接口,会调用相应的方法,使Bean能够访问Spring容器的特定资源
4@PostConstruct在Bean的依赖项注入完成后被调用,用于执行Bean的初始化逻辑
5InitializingBean#afterPropertiesSet()如果Bean实现了InitializingBean接口,在所有的属性设置完毕并且依赖注入完成后调用
6@Bean#initMethod()如果在Bean的配置中指定了init-method属性,会调用指定的初始化方法

Bean销毁过程方法调用顺序

调用顺序方法/注解描述
1@PreDestroy在Bean即将被销毁之前调用,允许Bean执行一些资源清理的逻辑
2DisposableBean#destroy()如果Bean实现了DisposableBean接口,在Bean销毁时调用
3@Bean#destroyMethod()如果在Bean的配置中指定了destroy-method属性,会调用指定的销毁方法

BeanPostProcessor

BeanPostProcessor内部执行顺序

生命周期阶段事件/回调方法相关的BeanPostProcessor方法备注
实例化前无直接事件BeanFactoryPostProcessor.postProcessBeanFactory对BeanFactory进行后处理,此时Bean尚未实例化。
实例化Bean构造函数被调用无直接BeanPostProcessor方法Bean对象被创建,但属性尚未注入。
属性注入后无直接事件BeanPostProcessor.postProcessBeforeInitialization在Bean初始化之前调用,此时Bean的属性已注入,但自定义初始化方法尚未调用。
初始化InitializingBean.afterPropertiesSet 或 自定义的init方法无直接BeanPostProcessor方法,但在上一阶段和下一阶段之间执行执行Bean的自定义初始化逻辑。
初始化后无直接事件BeanPostProcessor.postProcessAfterInitialization在Bean初始化方法执行完毕后调用,此时Bean已完全初始化。
销毁前无直接事件无直接BeanPostProcessor方法在Bean销毁之前,可以通过DisposableBean.destroy或自定义的destroy-method进行资源清理。
销毁DisposableBean.destroy 或 自定义的destroy方法无直接BeanPostProcessor方法执行Bean的自定义销毁逻辑。

请注意,BeanFactoryPostProcessorBeanPostProcessor不同,它处理的是BeanFactory,而不是单个Bean。此外,BeanPostProcessor的两个方法postProcessBeforeInitializationpostProcessAfterInitialization分别在Bean的初始化方法之前和之后被调用。

此表格主要是为了展示Bean的生命周期阶段和与之相关的回调方法或事件。在实际应用中,开发者可以通过实现相应的接口或配置自定义的初始化/销毁方法来参与Bean的生命周期管理。

BeanPostProcessor子类及其调用顺序相关因素

子类/实现调用顺序确定因素描述
自定义BeanPostProcessor注册顺序按照在Spring配置中定义或扫描的顺序进行调用。
实现了Ordered接口的BeanPostProcessor实现优先级通过实现Ordered接口的getOrder()方法提供一个顺序值,值越小优先级越高。
使用@Order注解的BeanPostProcessor注解优先级使用@Order注解并指定一个值来确定调用顺序,值越小优先级越高。
依赖关系的BeanPostProcessor依赖关系如果存在依赖关系,被依赖的BeanPostProcessor会先被调用。
其他默认BeanPostProcessor默认顺序没有指定顺序的BeanPostProcessor按照默认顺序调用,通常基于注册顺序。

请注意,这个表格是为了说明影响BeanPostProcessor子类调用顺序的不同因素。实际上,在编写自定义的BeanPostProcessor时,并不一定会直接扩展BeanPostProcessor接口的子类,而是直接实现BeanPostProcessor接口,并根据需要实现Ordered接口或使用@Order注解来指定调用顺序。

此外,表格中的“自定义BeanPostProcessor”指的是开发者自己实现的BeanPostProcessor接口,而不是指一个具体的子类。开发者在实现自定义的BeanPostProcessor时,应该遵循Spring框架的规范,确保处理器能够在Bean的生命周期中正确地执行。

bean的扩展点

ApplicationContextAware

ApplicationContext是我们常用的IOC容器,而他的顶层接口便是BeanFactory,ApplicationContext对BeanFactory做了拓展,功能更加强大。

@Component
public class SpringtUtil implements ApplicationContextAware {private static ApplicationContext applicationContext = null;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {SpringtUtil.applicationContext = applicationContext;}public static ApplicationContext getApplicationContext() {return applicationContext;}
}

ApplicationContextInitializer

用于在spring容器刷新之前初始化Spring ConfigurableApplicationContext的回调接口。
通常用于需要对应用程序上下文进行编程初始化的web应用程序中。例如,根据上下文环境注册属性源或激活配置文件等。

public class MyApplicationContextInitializer implements ApplicationContextInitializer {@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {System.out.println("-----MyApplicationContextInitializer initialize-----");}
}

mian函数中添加

@SpringBootApplication
public class MySpringBootApplication {public static void main(String[] args) {SpringApplication application = new SpringApplication(MySpringBootApplication.class);application.addInitializers(new MyApplicationContextInitializer());application.run(args);}
}

配置文件中配置 application.properties

context.initializer.classes=org.springframework.boot.demo.common.MyApplicationContextInitializer

SpringBoot的SPI扩展—META-INF/spring.factories中配置

org.springframework.context.ApplicationContextInitializer=org.springframework.boot.demo.common.MyApplicationContextInitializer

BeanPostProcessor

BeanPostProcessor,中文名 Bean的后置处理器,在Bean创建的过程中起作用。
BeanPostProcessor是Bean在创建过程中一个非常重要的扩展点,因为每个Bean在创建的各个阶段,都会回调BeanPostProcessor及其子接口的方法。

例子:简单地打印了Bean的名字

@Component  
public class LoggingBeanPostProcessor implements BeanPostProcessor {  @Override  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {StringBuilder sb = new  StringBuilder("Before Initialization:	");String fullName = bean.getClass().getName();sb.append(fullName);if(!fullName.equals(beanName)) {sb.append(",	aliasName=	").append(beanName);}System.err.println(sb);  return bean; // 直接返回传入的bean,不做额外处理  }  @Override  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {  
//        System.out.println("After Initialization : " + beanName);  return bean; // 直接返回传入的bean,不做额外处理  }  
}
父类名类名作用实际使用
BeanPostProcessorAutowiredAnnotationBeanPostProcessor处理 @Autowired@Value 注解,实现自动装配在 Spring 应用程序中自动注入依赖
BeanPostProcessorRequiredAnnotationBeanPostProcessor检查带有 @Required 注解的 bean 属性是否已设置确保必需属性被正确注入
BeanPostProcessorCommonAnnotationBeanPostProcessor处理 JSR-250 注解(如 @PostConstruct, @PreDestroy, @Resource在 bean 生命周期中调用注解方法,处理资源注入
BeanPostProcessorPersistenceAnnotationBeanPostProcessor扫描并处理 JPA 相关注解(如 @Entity集成 JPA 实体类到 Spring 应用程序中
BeanPostProcessorAsyncAnnotationBeanPostProcessor处理 @Async 注解,使方法异步执行在 Spring 应用程序中创建异步任务
BeanPostProcessorScheduledAnnotationBeanPostProcessor处理 @Scheduled 注解,按计划执行方法在 Spring 应用程序中创建定时任务
BeanPostProcessor自定义 BeanPostProcessor允许开发者自定义 bean 的初始化逻辑插入自定义代码到 bean 初始化过程

请注意,这个表格是为了提供信息而简化的,并且可能不包含所有 BeanPostProcessor 的实现。此外,随着 Spring 框架的发展,可能会有新的实现类被添加或现有类的用途发生变化。因此,建议参考 Spring 官方文档以获取最新和详细的信息。

InitializingBean

InitializingBean接口为bean提供了属性初始化后的处理方法,它只有一个afterPropertiesSet方法,凡是继承该接口的类,在bean的属性初始化后都会执行该方法。

构造一个bean的执行顺序

@Component
public class MyInitializingBean implements InitializingBean {public MyInitializingBean() {System.out.println("我是MyInitializingBean构造方法执行...");}@PostConstructpublic void postConstruct() {System.out.println("我是postConstruct方法执行...");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("我是afterPropertiesSet方法执行...");}@Bean(initMethod = "init")public MyInitializingBean test() {return new MyInitializingBean();}public void init(){System.out.println("我是init方法执行...");}// 打印顺序:// 构造方法 > postConstruct >afterPropertiesSet > init方法
}

常见的Aware接口

在Spring框架中,常见的Aware接口允许Bean在其生命周期内感知并访问Spring容器的特定资源或功能。以下是一些常见的Aware接口以及它们的简要描述,以表格的形式呈现:

接口名称描述
ApplicationContextAware允许Bean访问它所在的ApplicationContext,从而能够使用应用上下文的功能,如资源加载、事件发布等。
BeanNameAware提供了Bean的名称,允许Bean知道它在Spring容器中的名字。
BeanFactoryAware允许Bean访问它所在的BeanFactory,从而可以查询其他Bean或容器的状态。
EnvironmentAware允许Bean访问Spring的Environment,用于读取配置属性、系统属性等。
ResourceLoaderAware提供了对资源加载器的访问,允许Bean加载外部资源,如配置文件、图片等。
ApplicationEventPublisherAware允许Bean访问ApplicationEventPublisher,从而可以发布应用事件到Spring容器中。
MessageSourceAware提供了对MessageSource的访问,用于获取本地化消息,支持国际化。

相关文章:

  • 【高质量精品】2024美赛B题22页word版高质量半成品论文+多版保奖思路+数据+前四问思路代码等(后续会更新)
  • 杨中科 ASP.NETCORE 高级14 SignalR
  • Python循环语句——while循环的嵌套应用
  • 《Python 网络爬虫简易速速上手小册》第8章:分布式爬虫设计(2024 最新版)
  • Architecture Lab:Part C【流水线通用原理/Y86-64的流水线实现/实现IIADDQ指令】
  • 搭建游戏应该选择什么样的服务器?
  • C++类与对象(下)
  • JSR303参数校验-SpringMVC
  • Docker下安装GitLab
  • jmeter-02切换中文,改为白色背景
  • 深入理解Netty及核心组件使用—上
  • 通过神经网络模拟人类大脑的学习过程
  • 计算机网络-差错控制(纠错编码 海明码 纠错方法)
  • Linux|Grep 命令的 12 个实用示例
  • Docker Network
  • [PHP内核探索]PHP中的哈希表
  • 「面试题」如何实现一个圣杯布局?
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • 【跃迁之路】【735天】程序员高效学习方法论探索系列(实验阶段492-2019.2.25)...
  • ➹使用webpack配置多页面应用(MPA)
  • CSS3 变换
  • Electron入门介绍
  • Essential Studio for ASP.NET Web Forms 2017 v2,新增自定义树形网格工具栏
  • fetch 从初识到应用
  • jquery ajax学习笔记
  • Js基础知识(一) - 变量
  • Linux链接文件
  • React系列之 Redux 架构模式
  • scrapy学习之路4(itemloder的使用)
  • Vim 折腾记
  • Vue2.x学习三:事件处理生命周期钩子
  • vue-loader 源码解析系列之 selector
  • Vultr 教程目录
  • Xmanager 远程桌面 CentOS 7
  • 大快搜索数据爬虫技术实例安装教学篇
  • ------- 计算机网络基础
  • 思考 CSS 架构
  • 微信小程序填坑清单
  • 小程序、APP Store 需要的 SSL 证书是个什么东西?
  • 自制字幕遮挡器
  • k8s使用glusterfs实现动态持久化存储
  • PostgreSQL之连接数修改
  • 阿里云服务器如何修改远程端口?
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • ​ArcGIS Pro 如何批量删除字段
  • # include “ “ 和 # include < >两者的区别
  • (13):Silverlight 2 数据与通信之WebRequest
  • (pojstep1.3.1)1017(构造法模拟)
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (附源码)springboot 个人网页的网站 毕业设计031623
  • (附源码)ssm教师工作量核算统计系统 毕业设计 162307
  • (附源码)小程序儿童艺术培训机构教育管理小程序 毕业设计 201740
  • (免费领源码)Java#Springboot#mysql农产品销售管理系统47627-计算机毕业设计项目选题推荐
  • (太强大了) - Linux 性能监控、测试、优化工具
  • (循环依赖问题)学习spring的第九天