在 Spring Boot 中,有多种方式可以在应用启动时执行特定代码。以下是常见的几种方式:
1. 使用 CommandLineRunner
接口
CommandLineRunner
是 Spring Boot 提供的一个接口,实现该接口的run
方法可以在应用启动后执行特定代码。- 如果有多个
CommandLineRunner
,可以通过@Order
注解或实现Ordered
接口来指定执行顺序。
import org.springframework.boot.CommandLineRunner;import org.springframework.stereotype.Component;@Componentpublic class MyCommandLineRunner implements CommandLineRunner {@Overridepublic void run(String... args) throws Exception {System.out.println("应用启动时执行特定代码 - CommandLineRunner");}}import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; @Component public class MyCommandLineRunner implements CommandLineRunner { @Override public void run(String... args) throws Exception { System.out.println("应用启动时执行特定代码 - CommandLineRunner"); } }import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; @Component public class MyCommandLineRunner implements CommandLineRunner { @Override public void run(String... args) throws Exception { System.out.println("应用启动时执行特定代码 - CommandLineRunner"); } }
2. 使用 ApplicationRunner
接口
ApplicationRunner
与CommandLineRunner
类似,但它的run
方法接收的是ApplicationArguments
对象,可以更方便地处理命令行参数。
import org.springframework.boot.ApplicationArguments;import org.springframework.boot.ApplicationRunner;import org.springframework.stereotype.Component;@Componentpublic class MyApplicationRunner implements ApplicationRunner {@Overridepublic void run(ApplicationArguments args) throws Exception {System.out.println("应用启动时执行特定代码 - ApplicationRunner");}}import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; @Component public class MyApplicationRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { System.out.println("应用启动时执行特定代码 - ApplicationRunner"); } }import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; @Component public class MyApplicationRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { System.out.println("应用启动时执行特定代码 - ApplicationRunner"); } }
3. 使用 @PostConstruct
注解
@PostConstruct
是 JSR-250 提供的注解,标记在方法上后,Spring 会在依赖注入完成后调用该方法。- 这种方式适用于在 Bean 初始化时执行代码。
import javax.annotation.PostConstruct;import org.springframework.stereotype.Component;@Componentpublic class MyPostConstructBean {@PostConstructpublic void init() {System.out.println("Bean 初始化时执行特定代码 - @PostConstruct");}}import javax.annotation.PostConstruct; import org.springframework.stereotype.Component; @Component public class MyPostConstructBean { @PostConstruct public void init() { System.out.println("Bean 初始化时执行特定代码 - @PostConstruct"); } }import javax.annotation.PostConstruct; import org.springframework.stereotype.Component; @Component public class MyPostConstructBean { @PostConstruct public void init() { System.out.println("Bean 初始化时执行特定代码 - @PostConstruct"); } }
4. 使用 ApplicationListener
监听 ApplicationReadyEvent
事件
- Spring Boot 提供了多种应用事件,可以通过实现
ApplicationListener
接口来监听这些事件。 ApplicationReadyEvent
事件表示应用已完全启动,可以安全地执行代码。
import org.springframework.boot.context.event.ApplicationReadyEvent;import org.springframework.context.ApplicationListener;import org.springframework.stereotype.Component;@Componentpublic class MyApplicationListener implements ApplicationListener<ApplicationReadyEvent> {@Overridepublic void onApplicationEvent(ApplicationReadyEvent event) {System.out.println("应用完全启动后执行特定代码 - ApplicationListener");}}import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; @Component public class MyApplicationListener implements ApplicationListener<ApplicationReadyEvent> { @Override public void onApplicationEvent(ApplicationReadyEvent event) { System.out.println("应用完全启动后执行特定代码 - ApplicationListener"); } }import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; @Component public class MyApplicationListener implements ApplicationListener<ApplicationReadyEvent> { @Override public void onApplicationEvent(ApplicationReadyEvent event) { System.out.println("应用完全启动后执行特定代码 - ApplicationListener"); } }
5. 使用 @EventListener
注解
- 与
ApplicationListener
类似,但可以使用@EventListener
注解来简化代码。
import org.springframework.boot.context.event.ApplicationReadyEvent;import org.springframework.context.event.EventListener;import org.springframework.stereotype.Component;@Componentpublic class MyEventListener {@EventListener(ApplicationReadyEvent.class)public void onApplicationReady() {System.out.println("应用完全启动后执行特定代码 - @EventListener");}}import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; @Component public class MyEventListener { @EventListener(ApplicationReadyEvent.class) public void onApplicationReady() { System.out.println("应用完全启动后执行特定代码 - @EventListener"); } }import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; @Component public class MyEventListener { @EventListener(ApplicationReadyEvent.class) public void onApplicationReady() { System.out.println("应用完全启动后执行特定代码 - @EventListener"); } }
6. 在 @Bean
方法中直接编写初始化逻辑
- 在配置类中定义
@Bean
方法时,可以直接在方法体中编写初始化逻辑。
import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class MyConfig {@Beanpublic String initBean() {System.out.println("Bean 初始化时执行特定代码 - @Bean");return "Initialized Bean";}}import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyConfig { @Bean public String initBean() { System.out.println("Bean 初始化时执行特定代码 - @Bean"); return "Initialized Bean"; } }import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyConfig { @Bean public String initBean() { System.out.println("Bean 初始化时执行特定代码 - @Bean"); return "Initialized Bean"; } }
7. 使用 SpringApplication
的 run
方法
- 在
main
方法中,可以在SpringApplication.run()
之后直接编写代码。
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);System.out.println("应用启动后执行特定代码 - main 方法");}}import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); System.out.println("应用启动后执行特定代码 - main 方法"); } }import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); System.out.println("应用启动后执行特定代码 - main 方法"); } }
8. 使用 InitializingBean
接口
- 实现
InitializingBean
接口的afterPropertiesSet
方法,可以在 Bean 初始化时执行代码。
import org.springframework.beans.factory.InitializingBean;import org.springframework.stereotype.Component;@Componentpublic class MyInitializingBean implements InitializingBean {@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("Bean 初始化时执行特定代码 - InitializingBean");}}import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Component; @Component public class MyInitializingBean implements InitializingBean { @Override public void afterPropertiesSet() throws Exception { System.out.println("Bean 初始化时执行特定代码 - InitializingBean"); } }import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Component; @Component public class MyInitializingBean implements InitializingBean { @Override public void afterPropertiesSet() throws Exception { System.out.println("Bean 初始化时执行特定代码 - InitializingBean"); } }
9. 使用 @Configuration
类的静态代码块
- 在配置类中使用静态代码块,可以在类加载时执行代码。
import org.springframework.context.annotation.Configuration;@Configurationpublic class MyStaticConfig {static {System.out.println("配置类加载时执行特定代码 - 静态代码块");}}import org.springframework.context.annotation.Configuration; @Configuration public class MyStaticConfig { static { System.out.println("配置类加载时执行特定代码 - 静态代码块"); } }import org.springframework.context.annotation.Configuration; @Configuration public class MyStaticConfig { static { System.out.println("配置类加载时执行特定代码 - 静态代码块"); } }
总结
- 推荐方式:
CommandLineRunner
和ApplicationRunner
是最常用的方式,适合在应用启动后执行初始化逻辑。 - 灵活选择:根据具体需求选择合适的方式,例如:
- 如果需要处理命令行参数,使用
ApplicationRunner
。 - 如果需要在 Bean 初始化时执行代码,使用
@PostConstruct
或InitializingBean
。 - 如果需要监听应用事件,使用
ApplicationListener
或@EventListener
。
- 如果需要处理命令行参数,使用
这些方式都可以在 Spring Boot 启动时执行特定代码,选择合适的方式可以提高代码的可读性和可维护性。
THE END
暂无评论内容