Spring Boot中的8种初始化方法

Spring Boot中的8种初始化方法

1. @PostConstruct

@PostConstruct 是 Java 的标准注解,它标记的方法会在依赖注入完成后立即被调用。

import javax.annotation.PostConstruct;

import org.springframework.stereotype.Component;

@Component

public class MyPostConstructBean {

@PostConstruct

public void init() {

System.out.println("PostConstruct执行");

}

}

特点:

适用于简单的初始化逻辑。

依赖注入完成后立即执行。

执行顺序较早。

2. InitializingBean 接口

实现 InitializingBean 接口并重写 afterPropertiesSet 方法,也是进行初始化操作的一种方式。

import org.springframework.beans.factory.InitializingBean;

import org.springframework.stereotype.Component;

@Component

public class MyInitializingBean implements InitializingBean {

@Override

public void afterPropertiesSet() {

System.out.println("InitializingBean接口的afterProperiesSet执行");

}

}

特点:

比 @PostConstruct 更具可读性,适合复杂的初始化逻辑。

依赖注入完成后调用。

执行顺序与 @PostConstruct 类似,但稍晚。

3. @Bean 注解中的 initMethod

使用 @Configuration 配置类中的 @Bean 注解时,可以指定 initMethod 属性来定义初始化方法。

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

@Configuration

public class MyConfig {

@Bean(initMethod = "init")

public MyBean myBean() {

return new MyBean();

}

}

class MyBean {

public void init() {

System.out.println("@Bean的initMethod方法执行");

}

}

特点:

明确指定初始化方法。

更易于配置和管理初始化逻辑。

执行顺序在 @PostConstruct 和 InitializingBean 之后。

4. CommandLineRunner 接口

实现 CommandLineRunner 接口的组件会在 Spring Boot 应用启动完成后执行。

import org.springframework.boot.CommandLineRunner;

import org.springframework.stereotype.Component;

@Component

public class MyCommandLineRunner implements CommandLineRunner {

@Override

public void run(String... args) {

System.out.println("CommandLineRunner接口的run方法执行");

}

}

特点:

用于需要在应用完全启动后执行的初始化逻辑。

接受应用启动参数。

执行顺序在所有 Spring 组件初始化完成之后。

5. ApplicationRunner 接口

与 CommandLineRunner 类似,但提供了更高级的参数解析能力。

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) {

System.out.println("ApplicationRunner接口的run方法执行");

}

}

特点:

与 CommandLineRunner 相似,但具有更强的参数处理能力。

用于需要在应用完全启动后执行的初始化逻辑。

执行顺序与 CommandLineRunner 相同。

6. @EventListener事件监听

使用 @EventListener 注解,可以在应用启动的某个生命周期阶段执行初始化逻辑。比如监听 ContextRefreshedEvent 事件,这个事件会在 Spring 上下文初始化或刷新时发布。

import org.springframework.context.event.ContextRefreshedEvent;

import org.springframework.context.event.EventListener;

import org.springframework.stereotype.Component;

@Component

public class MyContextRefreshedListener {

@EventListener

public void handleContextRefreshed(ContextRefreshedEvent event) {

System.out.println("@EventListener监听ContextRefreshedEvent事件执行");

}

}

特点:

适用于需要在特定生命周期事件发生时执行的初始化逻辑。

可以监听各种生命周期事件,如 ContextRefreshedEvent、ContextClosedEvent 等。

7. SmartInitializingSingleton

实现 SmartInitializingSingleton 接口的 afterSingletonsInstantiated 方法,可以在所有单例 bean 都初始化完成后执行。

import org.springframework.beans.factory.SmartInitializingSingleton;

import org.springframework.stereotype.Component;

@Component

public class MySmartInitializingSingleton implements SmartInitializingSingleton {

@Override

public void afterSingletonsInstantiated() {

System.out.println("SmartInitializingSingleton接口的afterSingletonsInstantiated方法执行");

}

}

特点:

在所有单例 bean 初始化完成后执行。

适用于需要确保所有单例 bean 都已准备好时执行的初始化逻辑。

8. ApplicationListener

实现 ApplicationListener 接口,可以监听特定的 Spring 事件,如 ApplicationReadyEvent,这个事件在 Spring 应用完全启动后触发。

import org.springframework.boot.context.event.ApplicationReadyEvent;

import org.springframework.context.ApplicationListener;

import org.springframework.stereotype.Component;

@Component

public class MyApplicationReadyListener implements ApplicationListener {

@Override

public void onApplicationEvent(ApplicationReadyEvent event) {

System.out.println("监听ApplicationReadyEvent事件,ApplicationListener接口的onApplicationEvent方法执行");

}

}

特点:

用于在应用完全启动后执行逻辑。

可以监听各种 Spring 事件,提供灵活的初始化时机。

执行顺序综合比较

下面通过代码测试来看看它们的执行顺序,先准备以下代码,通过@Bean创建ExampleBean,在ExampleBean中放入了各种初始化的方式。

@Configuration

public class ExampleConfig {

@Bean(initMethod = "initMethod")

public ExampleBean initExampleBean() {

return new ExampleBean();

}

}

import org.springframework.beans.factory.InitializingBean;

import org.springframework.beans.factory.SmartInitializingSingleton;

import org.springframework.boot.ApplicationArguments;

import org.springframework.boot.ApplicationRunner;

import org.springframework.boot.CommandLineRunner;

import org.springframework.boot.context.event.ApplicationReadyEvent;

import org.springframework.context.ApplicationListener;

import org.springframework.context.event.ContextRefreshedEvent;

import org.springframework.context.event.EventListener;

import javax.annotation.PostConstruct;

public class ExampleBean implements InitializingBean, CommandLineRunner, ApplicationRunner, SmartInitializingSingleton,

ApplicationListener {

public ExampleBean() {

System.out.println("构造器执行");

}

@Override

public void afterPropertiesSet() {

System.out.println("InitializingBean接口的afterProperiesSet执行");

}

@Override

public void run(String... args) {

System.out.println("CommandLineRunner接口的run方法执行");

}

@Override

public void run(ApplicationArguments args) {

System.out.println("ApplicationRunner接口的run方法执行");

}

@Override

public void afterSingletonsInstantiated() {

System.out.println("SmartInitializingSingleton接口的afterSingletonsInstantiated方法执行");

}

@Override

public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {

System.out.println("监听ApplicationReadyEvent事件,ApplicationListener接口的onApplicationEvent方法执行");

}

@PostConstruct

public void postConstruct() {

System.out.println("PostConstruct执行");

}

public void initMethod() {

System.out.println("@Bean标的initMethod方法执行");

}

@EventListener

public void handleContextRefreshed(ContextRefreshedEvent event) {

System.out.println("@EventListener监听ContextRefreshedEvent事件执行");

}

}

启动项目运行之后,下面是控制台日志输出结果:

构造器执行

PostConstruct执行

InitializingBean接口的afterProperiesSet执行

@Bean标的initMethod方法执行

SmartInitializingSingleton接口的afterSingletonsInstantiated方法执行

@EventListener监听ContextRefreshedEvent事件执行

...

com.pujiho.practice.MyApplication : Started LoginApplication in 2.587 seconds (JVM running for 6.749)

...

ApplicationRunner接口的run方法执行

CommandLineRunner接口的run方法执行

监听ApplicationReadyEvent事件,ApplicationListener接口的onApplicationEvent方法执行

所以,综合所有提到的初始化方式,以下是它们的大致执行顺序:

@PostConstruct

InitializingBean.afterPropertiesSet

@Bean 的 initMethod

SmartInitializingSingleton.afterSingletonsInstantiated

@EventListener (如 ContextRefreshedEvent)

ApplicationRunner.run

CommandLineRunner.run

ApplicationListener (如 ApplicationReadyEvent)

结语

在 Spring Boot 中,选择合适的初始化方式取决于你的具体需求和初始化逻辑的复杂程度。@PostConstruct 和 InitializingBean 适合早期的、简单的初始化操作,而 CommandLineRunner 和 ApplicationRunner 更适合在应用完全启动后执行的复杂逻辑。了解这些初始化方式的执行顺序和特点,能够帮助你在项目中做出最佳选择,确保应用的平稳启动。

相关数据