工作中常用springboot启动后执行的方法

前言:

工作中难免会遇到一些,程序启动之后需要提前执行的需求。

例如:

  • 初始化缓存:在启动时加载必要的缓存数据。
  • 定时任务创建或启动:程序启动后创建或启动定时任务。
  • 程序启动完成通知:程序启动完成后通过邮件、短信等方式通知运维人员。
  • 外部系统同步:启动后与外部系统同步数据。

下面介绍几种常见方式:

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,因为其更加灵活。

相关推荐
Rain的Java大神之路16 分钟前
面试被LeetCode 27(移除元素)问懵?别再用两层 for 循环了:一道“简单题”吃透双指针原地删除,附面试加分话术 + 11 个避坑清单
后端·leetcode·面试
悟天特斯17 分钟前
安防一体化:从“各管各的“到“全局联动“
java·大数据·网络·人工智能·物联网
70后写java的老码农26 分钟前
Spring Boot 3.x + ShardingSphere 5.x + MyBatis-Plus 3.x:订单分库分表实战(含两个踩坑记录)
java
霸道流氓气质30 分钟前
AI 翻译插件:翻译记忆级联复用、术语混合检索与结构化质量门禁的 Vue3 + Spring AI 生产级实战
java·人工智能·spring
斯维赤37 分钟前
OCR到底是接入第三方API 还是自己封装?
java·ocr
利威尔xu43 分钟前
Go IM 源码实战(11):token 只是个 HASH,多端互踢的顺序错了就踢错人
后端·微服务·面试·架构·golang
码智社1 小时前
Redis 哨兵模式详解:从原理到生产实践
java·redis
救救孩子把1 小时前
结构化输出为何“格式正确、答案错误”?JSON Schema 的能力边界
android·java·json·agent·agent服务
猿究院--Cu-Sn合金1 小时前
Spring Boot + DeepSeek 求职 Agent 实践:工具注册、多轮调用与简历 JD 对比
数据库·人工智能·spring boot·后端·deepseek
程序员cxuan1 小时前
别学 subagent 了,很可能要凉了。
后端·agent·ai编程