前言

系统任务:在项目启动阶段要做一些数据初始化操作,这些操作有一个共同的特点,只在项目启动时进行,以后都不再执行。

应用场景:例如配置文件加载,数据库初始化等操作

Spring Boot出现之前 解决方案

在 Servlet/Jsp 项目中,如果涉及到系统任务,例如在项目启动阶段要做一些数据初始化操作,这些操作有一个共同的特点,只在项目启动时进行,以后都不再执行,这里,容易想到web基础中的三大组件( Servlet、Filter、Listener )之一 Listener ,这种情况下,一般定义一个 ServletContextListener,然后就可以监听到项目启动和销毁,进而做出相应的数据初始化和销毁操作,例如下面这样:

public class MyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
//在这里做数据初始化操作
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
//在这里做数据备份操作
}
}

当然,这是基础 web 项目的解决方案,如果使用了 Spring Boot,那么我们可以使用更为简便的方式。

内容介绍

1.SpringBoot对于系统启动时执行的任务,提供了两种解决方案:CommandLineRunner和ApplicationRunner,两者差别主要在于参数。

2.SpringBoot项目启动时会遍历所有的CommandLineRunner和ApplicationRunner的实现类并调用其中的run方法@Order注解可对于这些实现类调用顺序进行排序。

CommandLineRunner

使用 CommandLineRunner 时,首先自定义 MyCommandLineRunner1 并且实现 CommandLineRunner 接口:

@Component
@Order(100)
public class MyCommandLineRunner1 implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
}
}

关于这段代码,我做如下解释:

  1. 首先通过 @Compoent 注解将 MyCommandLineRunner1 注册为Spring容器中的一个 Bean。
  2. 添加 @Order注解,表示这个启动任务的执行优先级,因为在一个项目中,启动任务可能有多个,所以需要有一个排序。@Order 注解中,数字越小,优先级越大,默认情况下,优先级的值为 Integer.MAX_VALUE,表示优先级最低。
  3. 在 run 方法中,写启动任务的核心逻辑,当项目启动时,run方法会被自动执行。
  4. run 方法的参数,来自于项目的启动参数,即项目入口类中,main方法的参数会被传到这里。

此时启动项目,run方法就会被执行,至于参数,可以通过两种方式来传递,如果是在 IDEA 中,可以通过如下方式来配置参数:

另一种方式,则是将项目打包,在命令行中启动项目,然后启动时在命令行传入参数,如下:

java -jar devtools-0.0.1-SNAPSHOT.jar 三国演义 西游记

注意,这里参数传递时没有key,直接写value即可,执行结果如下:

ApplicationRunner

ApplicationRunner 和 CommandLineRunner 功能一致,用法也基本一致,唯一的区别主要体现在对参数的处理上,ApplicationRunner 可以接收更多类型的参数(ApplicationRunner 除了可以接收 CommandLineRunner 的参数之外,还可以接收 key/value形式的参数)。

使用 ApplicationRunner ,自定义类实现 ApplicationRunner 接口即可,组件注册以及组件优先级的配置都和 CommandLineRunner 一致,如下:

@Component
@Order(98)
public class MyApplicationRunner1 implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
List<String> nonOptionArgs = args.getNonOptionArgs();
System.out.println("MyApplicationRunner1>>>"+nonOptionArgs);
Set<String> optionNames = args.getOptionNames();
for (String key : optionNames) {
System.out.println("MyApplicationRunner1>>>"+key + ":" + args.getOptionValues(key));
}
String[] sourceArgs = args.getSourceArgs();
System.out.println("MyApplicationRunner1>>>"+Arrays.toString(sourceArgs));
}
}

当项目启动时,这里的 run 方法就会被自动执行,关于 run 方法的参数 ApplicationArguments ,我说如下几点:

  1. args.getNonOptionArgs();可以用来获取命令行中的无key参数(和CommandLineRunner一样)。
  2. args.getOptionNames();可以用来获取所有key/value形式的参数的key。
  3. args.getOptionValues(key));可以根据key获取key/value 形式的参数的value。
  4. args.getSourceArgs(); 则表示获取命令行中的所有参数。

ApplicationRunner 定义完成后,传启动参数也是两种方式,参数类型也有两种,第一种和 CommandLineRunner 一致,第二种则是 –key=value 的形式,在 IDEA 中定义方式如下:

或者使用 如下启动命令:

java -jar devtools-0.0.1-SNAPSHOT.jar 三国演义 西游记 --age=99

运行结果如下:

总结

整体来说 ,这两种的用法的差异不大 ,主要体现在对参数的处理上,小伙伴可以根据项目中的实际情况选择合适的解决方案。

Spring Boot 系统启动任务定义的更多相关文章

  1. spring boot 学习10 定义springboot的两种方法

    使用spring boot的两种方法: A:继承spring-boot-starter-parent项目 这种方式很简单,只需要在POM里面添加parent父工程即可. B: 如果你不喜欢继承spri ...

  2. Spring Boot下Bean定义方式及调用方式

    我们知道如果我们要在一个类使用spring提供的bean对象,我们需要把这个类注入到spring容器中,交给spring容器进行管理,但是在实际当中,我们往往会碰到在一个普通的Java类中,想直接使用 ...

  3. spring boot 系统启动时运行代码(1)-@PostConstruct

    Application.java import org.springframework.boot.SpringApplication; import org.springframework.boot. ...

  4. Spring Boot 2.0 的快速入门(图文教程)

    摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! Spring Boot 2.0 的快速入门(图文教程) 大家都 ...

  5. Spring Boot 框架学习 (一)配置并运行Spring Boot 框架

    下载开发工具: 下载完成打开以后,第一步检查环境 查看jdk是否配置: 接着一定要注意,maven通常情况下它是没有给你配置的,要自行配置: 右键新建: 然后依赖选择web.跟Mybatis就行了. ...

  6. 如何基于Spring Boot搭建一个完整的项目

    前言 使用Spring Boot做后台项目开发也快半年了,由于之前有过基于Spring开发的项目经验,相比之下觉得Spring Boot就是天堂,开箱即用来形容是绝不为过的.在没有接触Spring B ...

  7. Spring Boot Freemarker特别篇之contextPath【从零开始学Spring Boot】(转)

    需求缘起:有人在群里@我:请教群主大神一个问题,spring boot  + freemarker 怎么获取contextPath 头疼死我了,网上没一个靠谱的 .我就看看之前博客中的 [Spring ...

  8. Spring Boot项目中如何定制拦截器

    本文首发于个人网站:Spring Boot项目中如何定制拦截器 Servlet 过滤器属于Servlet API,和Spring关系不大.除了使用过滤器包装web请求,Spring MVC还提供Han ...

  9. Spring Boot Freemarker特别篇之contextPath【从零开始学Spring Boot

      需求缘起:有人在群里@我:请教群主大神一个问题,spring boot  + freemarker 怎么获取contextPath 头疼死我了,网上没一个靠谱的 .我就看看之前博客中的 [Spri ...

随机推荐

  1. session 机制和 httpsession 详解 (转载)

    https://www.cnblogs.com/bjanzhuo/archive/2013/02/27/3575884.html 一.术语session 在我的经验里,session这个词被滥用的程度 ...

  2. 移动web开发之布局

    移动web开发流式布局 1.0 移动端基础 1.1浏览器现状 PC端常见浏览器:360浏览器.谷歌浏览器.火狐浏览器.QQ浏览器.百度浏览器.搜狗浏览器.IE浏览器. 移动端常见浏览器:UC浏览器,Q ...

  3. 焦大:seo该研究用户需求还是搜索算法

    http://www.wocaoseo.com/thread-62-1-1.html 上一篇博客我写了用户需求点是做seo排名最首要关注的东西,其实这个我在以前也一直说的,seo有两大核心,一个是检索 ...

  4. JavaScript函数的高级用法

    1.函数的定义和调用 1.1函数的定义方式 方式1 函数声明方式 function 关键字 (命名函数) function fn(){} 方式2 函数表达式(匿名函数) var fn = functi ...

  5. 路由策略Routing Policy和策略路由PBR的区别

    这是面试的时候问道的一个问题,这里跟大家分享一下 路由策略(Routing Policy)是为了改变网络流量所经过的途径而修改路由信息的技术: PBR(policy-based-route)是一种依据 ...

  6. C# OWC11

    public void OcwChart(int[] Data,string[] DataName,string Yname,string Xname,string ChartName,string ...

  7. Activiti7 zip部署,查询及其删除

    zip部署 package com.itheima.activiti; import org.activiti.engine.ProcessEngine; import org.activiti.en ...

  8. Oracle中真正稳妥的求三甲的方法

    坐地铁回家路上忽然想起,三甲排名可能为多个,只取三名岂不荒谬.不信请看下面数据: create table tb_score( id number(4,0) primary key, name nva ...

  9. 用Nginx将web请求引导到本机两个tomcat

    如何在本机启动两个tomcat请参考:https://www.cnblogs.com/xiandedanteng/p/12100461.html 而Nginx这边,将\conf\nginx.conf ...

  10. Cassandra使用的各种策略

    1. 背景介绍 Cassandra 使用分布式哈希表(DHT)来确定存储某一个数据对象的节点.在 DHT 里面,负责存储的节点以及数据对象都被分配一个 token.token 只能在一定的范围内取值, ...