网站首页 > 编程文章 正文
1. 简介
在 Spring Boot 应用开发中,初始化操作是非常关键的操作。它可以在应用启动时进行一系列预先设定的任务,例如加载配置文件、初始化数据库相关操作、预热缓存数据、注册全局事件监听器等。
合理的初始化能让应用启动即稳定高效。但很多开发者对 Spring Boot 提供的丰富初始化手段了解不深。别担心,本篇文章将为你详细介绍 Spring Boot 提供的 7 种初始化操作,通过代码示例,助你轻松掌握,灵活运用。
环境准备:准备下面的类,后续介绍的示例代码都会基于下面的类进行。
@Service
public class CommonService {
}
@Component
public class PackComponent {
@Resource
private CommonService commonService ;
}
2. 实战案例
2.1 @PostConstruct注解
该注解应用在Bean的方法上,在Bean的依赖注入完成以后执行。
// 构造函数中打印注入的CommonService
public PackComponent() {
System.err.printf("执行构造函数, commonService: %s%n", this.commonService) ;
}
// 添加初始化方法
@PostConstruct
public void init() {
System.err.printf("@PostConstruct 执行初始化方法init, commonService: %s%n", this.commonService) ;
}
启动容器,输出结果:
执行构造函数, commonService: null
@PostConstruct 执行初始化方法init, commonService: CommonService@7cfb4736
适用场景:单个Bean的简单初始化(如缓存预热、资源加载等)。
注意:
@PostConstruct 注解类型在 JDK 6 到 JDK 8 期间是标准 Java 库的一部分。然而,在 JDK 9 中,整个 javax.annotation 包从核心 Java 模块中分离了出来,并最终在 JDK 11 中被移除。自 Jakarta EE 9 起,该包现在位于 jakarta.annotation 之下。
2.2 InitializingBean接口
只需将我们的Bean实现该接口并重写afterPropertiesSet()方法。
@Component
public class PackComponent implements InitializingBean {
// ...
@Override
public void afterPropertiesSet() throws Exception {
System.err.printf("InitializingBean初始化bean, "
+ "commonService: %s%n", this.commonService) ;
}
}
启动容器,输出结果:
执行构造函数, commonService: null
InitializingBean初始化bean, commonService: CommonService@3811510
适用场景:说不出有什么特别的场景。不过来看看官方的建议是怎么说的:
建议您不要使用 InitializingBean 接口,因为它会将代码不必要地耦合到 Spring上。相反,我们建议使用 @PostConstruct 注解,或者指定一个 POJO 的初始化方法。
注意:该初始化动作在@PostConstruct之后执行。
2.3 @Bean的initMethod属性
通过@Bean注解定义bean时,我们可以通过设置initMethod属性来指定执行的初始化方法。
现有如下的类:
public class ThirdPartyComponent {
public void init() {
System.err.println("ThirdPartyComponent init...") ;
}
}
配置该类为Bean对象:
@Bean(initMethod = "init")
ThirdPartyComponent thirdPartyComponent() {
return new ThirdPartyComponent() ;
}
启动容器,输出结果:
ThirdPartyComponent init...
适用场景:第三方类(无法直接添加注解)的初始化。
注意:该初始化操作的执行是在@PostConstruct和InitializingBean之后执行。
2.4 ApplicationRunner或CommandLineRunner
将我们的bean实现其中任何一个接口都可以,在Spring Boot应用启动完成后执行。
执行时机:会在ApplicationContext上下完全准备就绪以后(refresh之后)。
@Component
public class PackComponent implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.err.println("通过CommandLineRunner执行初始化动作...") ;
}
}
启动容器,输出结果:
应用启动完成以后执行相应的Runner接口回调方法。
ApplicationRunner与CommandLineRunner的区别在于接收命令行参数方式不同。ApplicationRunner的回调方法接收ApplicationArguments参数,该对象支持解析命令行参数(如--key=value);CommandLineRunner则是直接接收原始命令行参数(String[])。
适用场景:应用启动后执行全局任务(如数据初始化,资源检查等)。
2.5 监听ContextRefreshedEvent事件
该事件会在ApplicationContext初始化或刷新完成后触发(refresh单例bean创建完成以后的最后一步finishRefresh方法),如下:
@Component
public class PackComponent implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
System.err.println("ApplicationContext初始化完成, 执行初始化操作") ;
}
}
启动容器,输出结果:
适用场景:适合应用到需Spring上下文初始化完成后执行全局性初始化操作的场景(如:字典数据,缓存,连接外部系统等)。
2.6
SmartInitializingSingleton接口
实现该接口后在所有的单例bean都创建完成以后执行该接口的回调方法
afterSingletonsInstantiated()。
执行时机:在@PostConstruct、InitializingBean之后,但在ApplicationRunner之前。
@Component
public class PackComponent implements SmartInitializingSingleton {
@Override
public void afterSingletonsInstantiated() {
System.err.println("SmartInitializingSingleton执行初始化操作") ;
}
}
启动容器,输出结果:
使用场景:依赖其他单例 Bean 的而全景初始化(如缓存预热,与上下文无关的初始化操作等)。
2.7 SmartLifecycle接口
SmartLifecycle 用于组件的生命周期管理。实现该接口可定义自定义初始化(start)和销毁(stop)逻辑。
执行时机:该接口的调用与2.5介绍的时机一样finishRefresh中,但是比ContextRefreshedEvent事件先执行。
@Component
public class PackComponent implements SmartLifecycle {
private volatile boolean running;
@Override
public void start() {
System.err.println("SmartLifecycle 执行初始化操作") ;
this.running = true ;
}
@Override
public void stop() {
this.running = false;
}
@Override
public boolean isRunning() {
return this.running ;
}
}
启动容器,输出结果:
适用场景:外部资源管理,缓存预热,异步消息处理等。
猜你喜欢
- 2025-05-09 Spring Boot3 RESTful 接口参数校验,这篇吃透就够了!
- 2025-05-09 《Spring6》第02节:基于XML方式搭建Spring6框架开发环境
- 2025-05-09 MapStruct架构设计(mapstruct @mapping)
- 2025-05-09 分布式微服务架构组件(分布式微服务架构设计)
- 2025-05-09 Java Swing组件下的JButton实例(java swing 组件)
- 2025-05-09 java基础都在这了,小主们拿去吧(java基础是指什么)
- 2025-05-09 AOP的实现落地(拦截过滤),一切都要从Servlet说起
- 2025-05-09 【Spring Boot】WebSocket 的 6 种集成方式
- 2025-05-09 Java 中五种最常见加密算法:原理、应用与代码实现
- 2025-05-09 用注解进行参数校验,spring validation介绍、使用、实现原理分析
你 发表评论:
欢迎- 05-09Spring Boot3 RESTful 接口参数校验,这篇吃透就够了!
- 05-09《Spring6》第02节:基于XML方式搭建Spring6框架开发环境
- 05-09MapStruct架构设计(mapstruct @mapping)
- 05-09分布式微服务架构组件(分布式微服务架构设计)
- 05-09Java Swing组件下的JButton实例(java swing 组件)
- 05-09java基础都在这了,小主们拿去吧(java基础是指什么)
- 05-09AOP的实现落地(拦截过滤),一切都要从Servlet说起
- 05-09【Spring Boot】WebSocket 的 6 种集成方式
- 最近发表
-
- Spring Boot3 RESTful 接口参数校验,这篇吃透就够了!
- 《Spring6》第02节:基于XML方式搭建Spring6框架开发环境
- MapStruct架构设计(mapstruct @mapping)
- 分布式微服务架构组件(分布式微服务架构设计)
- Java Swing组件下的JButton实例(java swing 组件)
- java基础都在这了,小主们拿去吧(java基础是指什么)
- AOP的实现落地(拦截过滤),一切都要从Servlet说起
- 【Spring Boot】WebSocket 的 6 种集成方式
- Java 中五种最常见加密算法:原理、应用与代码实现
- 用注解进行参数校验,spring validation介绍、使用、实现原理分析
- 标签列表
-
- spire.doc (59)
- system.data.oracleclient (61)
- 按键小精灵源码提取 (66)
- pyqt5designer教程 (65)
- 联想刷bios工具 (66)
- c#源码 (64)
- graphics.h头文件 (62)
- mysqldump下载 (66)
- sqljdbc4.jar下载 (56)
- libmp3lame (60)
- maven3.3.9 (63)
- 二调符号库 (57)
- 苹果ios字体下载 (56)
- git.exe下载 (68)
- diskgenius_winpe (72)
- pythoncrc16 (57)
- solidworks宏文件下载 (59)
- qt帮助文档中文版 (73)
- satacontroller (66)
- hgcad (64)
- bootimg.exe (69)
- android-gif-drawable (62)
- axure9元件库免费下载 (57)
- libmysqlclient.so.18 (58)
- springbootdemo (64)
本文暂时没有评论,来添加一个吧(●'◡'●)