SpringBoot启动后自动执行方法的各种方式对比

 更新时间:2025年04月29日 10:16:13   作者:饕餮争锋  
这篇文章主要为大家详细介绍了SpringBoot启动后自动执行方法的各种方式和性能对比,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下

1. SpringBoot启动后自动执行方法的各种方式

1.1 @PostConstruct 注解

作用:在依赖注入完成后执行初始化方法。

适用场景:需要在Bean初始化时执行某些操作(如配置、预加载数据)。

注意:该方法在Bean初始化阶段执行,此时应用可能未完全启动(如数据库连接未就绪)。

示例代码:

import javax.annotation.PostConstruct;
import org.springframework.stereotype.Component;
 
@Component
public class MyPostConstructBean {
    @PostConstruct
    public void init() {
        System.out.println("PostConstruct 方法执行");
        // 执行初始化逻辑
    }
}

1.2. 实现 InitializingBean 接口

作用:通过重写 afterPropertiesSet 方法实现初始化。

适用场景:需要在属性注入后执行操作,与 @PostConstruct 类似但需实现接口。

示例代码:

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("InitializingBean 的 afterPropertiesSet 方法执行");
        // 执行初始化逻辑
    }
}

1.3. 实现 ApplicationRunner 接口

作用:在Spring应用上下文刷新后执行,支持接收命令行参数。

适用场景:需要在应用启动完成后执行操作,此时Bean已初始化完毕。

示例代码:

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 执行");
        // 执行逻辑,可访问命令行参数 args
    }
}

1.4. 实现 CommandLineRunner 接口

作用:与 ApplicationRunner 类似,但参数为 String[]。

适用场景:需要接收简单命令行参数时使用。

示例代码:

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 执行");
        // 执行逻辑,可访问 args 参数
    }
}

1.5. 实现 ApplicationListener 接口

作用:通过 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("ApplicationReadyEvent 触发,应用已启动");
        // 执行逻辑,此时可安全访问所有Bean
    }
}

1.6. 使用 @Bean 的 initMethod 属性

作用:在Spring配置类中定义Bean时,通过 initMethod 指定初始化方法。

示例代码:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
@Configuration
public class AppConfig {
 
    @Bean(initMethod = "init")
    public MyBean myBean() {
        return new MyBean();
    }
}
 
public class MyBean {
    public void init() {
        System.out.println("应用启动后执行: initMethod");
        // 在这里添加初始化逻辑
    }
}

或使用 init-method 属性(XML 配置):

<bean id="myBean" class="com.example.MyBean" init-method="init"/>

2.各方式执行时机对比

方法执行时机
@PostConstructBean 初始化完成后(属性注入后)
InitializingBean与 @PostConstruct 类似,属性注入后
ApplicationRunner应用上下文刷新后,ApplicationReadyEvent 触发前
CommandLineRunner同上
ApplicationListener应用完全就绪(所有Bean初始化完成,所有启动任务执行完毕)

根据需求选择合适的方式:

  • 需要访问数据库或资源时,建议使用 ApplicationListener 或 CommandLineRunner。
  • 简单的Bean初始化逻辑可用 @PostConstruct 或 InitializingBean。

注意事项

  • 线程问题:默认在主线程执行,避免长时间阻塞操作,可考虑异步执行(如结合 @Async)。
  • 依赖注入:在 @PostConstruct 和 InitializingBean 中无法直接访问其他Bean(需等待初始化完成)。
  • 顺序控制:通过 @Order 或实现 Ordered 接口控制多个启动任务的顺序。

相关文档:Spring中InitializingBean接口和@PostConstruct注解的使用详解

3.使用 @Order 控制执行顺序

作用:通过 @Order 或实现 Ordered 接口控制多个启动任务的执行顺序。

示例:在 ApplicationRunner 中使用 @Order

import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
 
@Component
@Order(1)  // 数值越小优先级越高
public class FirstRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) {
        System.out.println("第一个执行的 Runner");
    }
}
 
@Component
@Order(2)
public class SecondRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) {
        System.out.println("第二个执行的 Runner");
    }
}

到此这篇关于SpringBoot启动后自动执行方法的各种方式对比的文章就介绍到这了,更多相关SpringBoot启动自动执行方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 一文详解Java如何自动生成简单的Mermaid类图

    一文详解Java如何自动生成简单的Mermaid类图

    这篇文章主要为大家详细介绍了Java如何自动生成简单的Mermaid类图,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-10-10
  • Java程序员必备的11大IntelliJ插件(附地址)

    Java程序员必备的11大IntelliJ插件(附地址)

    这篇文章主要介绍了Java程序员必备的11大IntelliJ插件(附地址),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • springboot整合mqtt实现消息订阅和推送功能

    springboot整合mqtt实现消息订阅和推送功能

    mica-mqtt-client-spring-boot-starter是一个方便、高效、可靠的MQTT客户端启动器,适用于需要使用MQTT协议进行消息通信的Spring Boot应用程序,这篇文章主要介绍了springboot整合mqtt实现消息订阅和推送功能,需要的朋友可以参考下
    2024-02-02
  • Mybatis中使用in()查询的方式详解

    Mybatis中使用in()查询的方式详解

    当参数有值,添加条件查询,附带一个字符串的in查询,下面这篇文章主要给大家介绍了关于Mybatis中使用in()查询的方式,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • 拦截JSP页面,校验是否已登录详解及实现代码

    拦截JSP页面,校验是否已登录详解及实现代码

    这篇文章主要介绍了拦截JSP页面,校验是否已登录详解及实现代码的相关资料,需要的朋友可以参考下
    2016-11-11
  • Java封装好的mail包发送电子邮件的类

    Java封装好的mail包发送电子邮件的类

    本文给大家分享了2个java封装好的mail包发送电子邮件的类,并附上使用方法,小伙伴们可以根据自己的需求自由选择。
    2016-01-01
  • SpringBoot使用swagger生成api接口文档的方法详解

    SpringBoot使用swagger生成api接口文档的方法详解

    在之前的文章中,使用mybatis-plus生成了对应的包,在此基础上,我们针对项目的api接口,添加swagger配置和注解,生成swagger接口文档,需要的可以了解一下
    2022-10-10
  • 如何用Java 几分钟处理完 30 亿个数据(项目难题)

    如何用Java 几分钟处理完 30 亿个数据(项目难题)

    现有一个 10G 文件的数据,里面包含了 18-70 之间的整数,分别表示 18-70 岁的人群数量统计,今天小编通过本文给大家讲解如何用Java 几分钟处理完 30 亿个数据,这个问题一直以来是项目难题,今天通过本文给大家详细介绍下,感兴趣的朋友一起看看吧
    2022-07-07
  • java并发编程中ReentrantLock可重入读写锁

    java并发编程中ReentrantLock可重入读写锁

    这篇文章主要介绍了java并发编程中ReentrantLock可重入读写锁,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • 详解Java七大阻塞队列之SynchronousQueue

    详解Java七大阻塞队列之SynchronousQueue

    SynchronousQueue不需要存储线程间交换的数据,它的作用像是一个匹配器,使生产者和消费者一一匹配。本文详细讲解了Java七大阻塞队列之一SynchronousQueue,需要了解的小伙伴可以参考一下这篇文章
    2021-09-09

最新评论