前言:
工作中难免会遇到一些,程序启动之后需要提前执行的需求。
例如:
- 初始化缓存:在启动时加载必要的缓存数据。
- 定时任务创建或启动:程序启动后创建或启动定时任务。
- 程序启动完成通知:程序启动完成后通过邮件、短信等方式通知运维人员。
- 外部系统同步:启动后与外部系统同步数据。
下面介绍几种常见方式:
1.使用@PostConstruct
注解:
使用@PostConstruct
注解可以在Spring容器初始化bean之后立即执行一个方法。这通常用于执行一些初始化任务,如加载配置、初始化资源等。
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class Test {
@PostConstruct
public void init(){
System.out.println("Test类先初始化啦>>>>>>>>");
}
}
2. 实现CommandLineRunner
接口
CommandLineRunner
接口允许你定义在Spring Boot应用程序启动后立即运行的方法。这个方法会接收一个字符串数组作为参数,通常用于处理命令行参数。
package com;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class TestCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("实现CommandLineRunner接口>>>>>>");
}
}
3. 实现ApplicationRunner
接口
ApplicationRunner
接口与CommandLineRunner
类似,但它接收的参数是ApplicationArguments
类型,提供了更丰富的命令行参数处理功能。这对于需要更复杂的命令行参数解析的情况很有用。
package com;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
@Component
public class TestApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("TestApplicationRunner实现ApplicationRunner接口>>>>>");
}
}
4.使用ApplicationListener,或者使用事件注@EventListener
- ApplicationStartedEvent事件
ApplicationStartedEvent事件在Spring Boot应用程序启动并开始运行,但在任何HTTP服务器启动之前触发。
package com;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class TestApplicationListenerStartedEvent implements ApplicationListener<ApplicationStartedEvent> {
@Override
public void onApplicationEvent(ApplicationStartedEvent applicationStartedEvent) {
System.out.println("实现ApplicationListener<ApplicationStartedEvent>接口>>>>>>>>>");
}
@EventListener(classes = {ApplicationStartedEvent.class})
public void ApplicationStartedEvent(){
System.out.println("采用事件监听注解@EventListener,监听ApplicationStartedEvent事件");
}
}
- ApplicationReadyEvent事件
ApplicationReadyEvent事件是在所有Spring Boot应用程序启动并且所有HTTP服务器都已经启动并监听端口后发布的事件。
package com;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class TestApplicationListenerReadyEvent implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
System.out.println("实现ApplicationListener<ApplicationStartedEvent>接口>>>>>>>>>");
}
@EventListener(classes = {ApplicationReadyEvent.class})
public void ApplicationReadyEvent(){
System.out.println("采用事件监听注解@EventListener,监听ApplicationReadyEvent事件");
}
}
执行顺序:
Test类先初始化啦>>>>>>>>
------------>ApplicationStartedEvent事件<--------------------
采用事件监听注解@EventListener,监听ApplicationStartedEvent事件
实现ApplicationListener<ApplicationStartedEvent>接口>>>>>>>>>
------------>ApplicationStartedEvent事件<--------------------
TestApplicationRunner实现ApplicationRunner接口>>>>>
TestCommandLineRunner实现CommandLineRunner接口>>>>>>
------------>ApplicationReadyEvent事件<--------------------
采用事件监听注解@EventListener,监听ApplicationReadyEvent事件
实现ApplicationListener<ApplicationStartedEvent>接口>>>>>>>>>
------------>ApplicationReadyEvent事件<--------------------
小结:
选择哪种方式取决于你的具体需求,例如是否需要处理命令行参数、是否需要在所有HTTP服务器都启动后执行代码、是否需要异步执行等。在大多数情况下,@PostConstruct
、CommandLineRunner
、ApplicationRunner
和监听ApplicationReadyEvent
事件是最常用的方法。一般生产中使用ApplicationRunner、CommandLineRunner,因为其更加灵活。