Spring Boot启动后自动执行任务解决方案

1.需求来源

日常开发中有时会要求 Spring 容器启动完成后,初始化一些资源加载,例如:解析配置文件完成 es 数据初始化或增量更新,自定义线程池初始化等工作。

2.解决方案

SpringBoot 给我们提供了两个接口来帮助我们实现这种需求。这两个接口分别为 CommandLineRunner和 ApplicationRunner。他们的执行时机为容器启动完成的时候。这两个接口中有一个 run 方法,我们只需要实现这个方法即可。这两个接口的不同之处在于:ApplicationRunner 中 run 方法的参数为ApplicationArguments,而 CommandLineRunner 接口中 run 方法的参数为 String 数组。

2.1.实现 CommandLineRunner 接口

@Slf4j
@Component
public class InitCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        log.info("读取String数组参数初始化操作内容...");
    }
}

项目启动效果

... 前面内容省略
2021-09-27 23:09:18.994  INFO 47408 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2021-09-27 23:09:18.995  INFO 35420 --- [  restartedMain] c.g.v.m.explorer.ExplorerApplication     : Started ExplorerApplication in 3.169 seconds (JVM running for 4.664)
2021-09-27 23:09:18.996  INFO 35420 --- [  restartedMain] c.g.v.m.e.runner.InitCommandLineRunner   : 读取String数组参数初始化操作内容...

2.2.实现 ApplicationRunner 接口

@Slf4j
@Component
public class InitApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("读取 ApplicationArguments 获取项目详细信息初始化操作内容...");
    }
}

项目启动效果

... 前面内容省略
2021-09-27 23:10:16.541  INFO 47408 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2021-09-27 23:10:16.542  INFO 35420 --- [  restartedMain] c.g.v.m.explorer.ExplorerApplication     : Started ExplorerApplication in 3.169 seconds (JVM running for 4.664)
2021-09-27 23:10:16.543  INFO 35420 --- [  restartedMain] c.g.v.m.e.runner.InitApplicationRunner   : 读取 ApplicationArguments 获取项目详细信息初始化操作内容...

2.3.顺序要求–@Order注解

实际开发中存储初始化加载执行顺序的要求场景,此时就可以使用 @Order 注解,它可以为多个在 spring 容器启动完成后,将接下来的 Runner 任务 按照排序 串行执行。例如:加了@Order(1) 注解的类实例 bean 优先于@Order(2) 注解的类实例 bean。

... 前面内容省略
2021-09-27 23:14:08.790  INFO 47408 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2021-09-27 23:14:08.792  INFO 47408 --- [  restartedMain] c.g.v.m.explorer.ExplorerApplication     : Started ExplorerApplication in 3.164 seconds (JVM running for 4.195)
2021-09-27 23:14:08.793  INFO 47408 --- [  restartedMain] c.g.v.m.e.runner.InitCommandLineRunner   : 读取String数组参数初始化操作内容...
2021-09-27 23:14:08.793  INFO 47408 --- [  restartedMain] c.g.v.m.e.runner.InitCommandLineRunner   : @Order(1)
2021-09-27 23:14:08.793  INFO 47408 --- [  restartedMain] c.g.v.m.e.runner.InitApplicationRunner   : 读取 ApplicationArguments 获取项目详细信息初始化操作内容...
2021-09-27 23:14:08.793  INFO 47408 --- [  restartedMain] c.g.v.m.e.runner.InitApplicationRunner   : @Order(2)

2.4.实际生产运用案例

1、初始化ES,同步表数据

/**
 * 初始化 需要同步数据到 ES index的数据
 */
@Slf4j
@Component
@Order(value = 2)
public class DataInitRunner implements ApplicationRunner {
	@Autowired
    private InitTables initTables;
    @Autowired
    private InitTablesDataService initTablesDataService;
    /**
     * 初始化es index
     */
    @Override
    public void run(ApplicationArguments args) {
        try {
            initTables.getList().forEach(initTablesDataService::initTablesData);
            log.info("elasticsearch同步数据成功...");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("elasticsearch同步数据失败...");
        }
    }
}

2、初始化本地存储路径

@Slf4j
@Component
@Order(1)
public class FilePathInitRunner implements ApplicationRunner {
    
    @Autowired
    private ExplorerConfig explorerConfig;

    public void run(ApplicationArguments args) throws Exception {
        File file = new File(explorerConfig.getRootDir());
        if (!file.exists()) {
            file.mkdirs();
            log.info("路径不存在,创建完成");
        }
        log.info("路径初始化完成");
    }

}

以上方案说明结束。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值