Spring Boot 2.0(七):Spring Boot 如何解决项目启动时初始化资源

在我们实际工作中,总会遇到这样需求,在项目启动的时候需要做一些初始化的操作,比如初始化线程池,提前加载好加密证书等。今天就给大家介绍一个 Spring Boot 神器,专门帮助大家解决项目启动初始化资源操作。

这个神器就是 CommandLineRunnerCommandLineRunner 接口的 Component 会在所有 SpringBeans都初始化之后, SpringApplication.run()之前执行,非常适合在应用程序启动之初进行一些数据初始化的工作。

接下来我们就运用案例测试它如何使用,在测试之前在启动类加两行打印提示,方便我们识别 CommandLineRunner 的执行时机。

@SpringBootApplication
public class CommandLineRunnerApplication {
    public static void main(String[] args) {
        System.out.println("The service to start.");
        SpringApplication.run(CommandLineRunnerApplication.class, args);
        System.out.println("The service has started.");
    }
}

接下来我们直接创建一个类继承 CommandLineRunner ,并实现它的 run() 方法。

@Component
public class Runner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("The Runner start to initialize ...");
    }
}

我们在 run() 方法中打印了一些参数来看出它的执行时机。完成之后启动项目进行测试:

...
The service to start.

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.0.RELEASE)
...
2018-04-21 22:21:34.706  INFO 27016 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2018-04-21 22:21:34.710  INFO 27016 --- [           main] com.neo.CommandLineRunnerApplication     : Started CommandLineRunnerApplication in 3.796 seconds (JVM running for 5.128)
The Runner start to initialize ...
The service has started.

根据控制台的打印信息我们可以看出 CommandLineRunner 中的方法会在 Spring Boot 容器加载之后执行,执行完成后项目启动完成。

如果我们在启动容器的时候需要初始化很多资源,并且初始化资源相互之间有序,那如何保证不同的 CommandLineRunner 的执行顺序呢?Spring Boot 也给出了解决方案。那就是使用 @Order 注解。

我们创建两个 CommandLineRunner 的实现类来进行测试:

第一个实现类:

@Component
@Order(1)
public class OrderRunner1 implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("The OrderRunner1 start to initialize ...");
    }
}

第二个实现类:

@Component
@Order(2)
public class OrderRunner2 implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("The OrderRunner2 start to initialize ...");
    }
}

添加完成之后重新启动,观察执行顺序:

...
The service to start.

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.0.RELEASE)
...
2018-04-21 22:21:34.706  INFO 27016 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2018-04-21 22:21:34.710  INFO 27016 --- [           main] com.neo.CommandLineRunnerApplication     : Started CommandLineRunnerApplication in 3.796 seconds (JVM running for 5.128)
The OrderRunner1 start to initialize ...
The OrderRunner2 start to initialize ...
The Runner start to initialize ...
The service has started.

通过控制台的输出我们发现,添加 @Order 注解的实现类最先执行,并且 @Order()里面的值越小启动越早。

在实践中,使用 ApplicationRunner也可以达到相同的目的,两着差别不大。

示例代码:https://github.com/ityouknow/spring-cloud-examples

原文发布于微信公众号 - 纯洁的微笑(keeppuresmile)

原文发表时间:2018-05-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏阿杜的世界

Spring Cloud学习-Eureka、Ribbon和Feign引子实践源码下载参考资料

看完《微服务设计》后,算是补上了自己在服务化这块的理论知识,在业界,一般有两种微服务的实践方法:基于dubbo的微服务架构、基于Spring Cloud的微服务...

2342
来自专栏Java帮帮-微信公众号-技术文章全总结

高级框架-SpringBoot【悟空教程】

Spring 诞生时是 Java 企业版(Java Enterprise Edition,JEE,也称 J2EE)的轻量级代替品。无需开发重量级的 Enterp...

4192
来自专栏大数据学习笔记

Hadoop基础教程-第13章 源码编译(13.1 Zookeeper源码编译)

第13章 源码编译 13.1 Zookeeper源码编译 13.1.1 安装Ant 注意,不要下载最新版,下载指定版本 http://archive.apa...

2455
来自专栏WindCoder

springBoot初探-创建项目

一边学习公司用到的技术,一边重构小程序后端,从而更好的理解公司搭建的框架。此处记录一个用idea+gradle+springboot的基础实现。

741
来自专栏一个默默无闻的工程师的日常

rabbitmq无法重新加入集群,启动失败的问题

3121
来自专栏java、Spring、技术分享

Eureka 服务提供者与消费者

1:修改pom.xml文件,与服务提供都不同的是这里需要引入spring-cloud-starter-ribbon 用于做负载均衡。服务提供都可能会部署多个实例...

2403
来自专栏乐沙弥的世界

Percona XtraDB Cluster添加仲裁节点

Galera Arbitrator是Percona XtraDB集群的成员,用于投票,以防您拥有少量服务器(通常为两个)并且不希望添加更多资源。Galera仲裁...

1822
来自专栏全栈

node 模块安装的问题,谁能帮我看看怎么回事

1311
来自专栏全栈架构

使用Spring Boot和Kotlin创建RESTfull API

使用 Kotlin 结合 SpringBoot 开发一个 RESTFul版本的 HelloWorld。

1073
来自专栏云计算小知识

Spring Boot 如何解决项目启动时初始化资源

在我们实际工作中,总会遇到这样需求,在项目启动的时候需要做一些初始化的操作,比如初始化线程池,提前加载好加密证书等。今天就给大家介绍一个 Spring Boot...

2272

扫码关注云+社区

领取腾讯云代金券