1. Introduction

I don’t know if you’ve been asked to implement some logic as soon as the project starts. Such as simple cache warm-up, or live broadcast and so on. If you are using the Spring Boot framework you can do this with its interface CommandLineRunner and ApplicationRunner.

2. CommandLineRunner

Org.springframework.boot.Com mandLineRunner is to provide an interface, Spring Boot when you implement this interface and into the Spring IoC container, Spring the Boot after application startup will perform its run method. There can be more than one implementation of CommandLineRunner in a Spring Boot, and when there are more than one, you can implement the Ordered interface to control the Order in which these implementations are executed (the higher the Order, the lower the priority). Let’s declare two implementations and specify the order:

Priority execution:

package cn.felord;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

/** * Highest priority * This class is expected to be executed in the first order after SpringBoot is started@author felord.cn
 * @since12:57 * * /
@Slf4j
@Component
public class HighOrderCommandLineRunner implements CommandLineRunner.Ordered {
    @Override
    public void run(String... args) throws Exception {
        for (String arg : args) {
            log.info("arg = " + arg);
        }
        log.info("i am highOrderRunner");
    }

    @Override
    public int getOrder(a) {
        return Integer.MIN_VALUE+1; }}Copy the code

Second order execution:

package cn.felord;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

/** * Priority is lower than {@code HighOrderCommandLineRunner}
 * @author felord.cn
 * @sinceThou * * /
@Slf4j
@Component
public class LowOrderCommandLineRunner implements CommandLineRunner.Ordered {

    @Override
    public void run(String... args) throws Exception {
        log.info("i am lowOrderRunner");
    }

    @Override
    public int getOrder(a) {
        return Integer.MIN_VALUE+1; }}Copy the code

After starting the Spring Boot application, the console prints out the results in the predetermined order:

The 23:11:03 2020-05-30. 11976-685 the INFO [main] O.S.B.W.E mbedded. Tomcat. TomcatWebServer: tomcat started on the port (s) : 8080 (http) with context path' '2020-05-30 23:11:03.701 INFO 11976 -- [main] c.f.plication: Started SpringBootApplicationin4.272 seconds (JVM is runningfor6.316) the 2020-05-30 23:11:03. 11976-706 the INFO [main] C.F.H ighOrderCommandLineRunner: I am highOrderRunner 23:11:03 2020-05-30. 11976-706 the INFO [main] C.F.L owOrderCommandLineRunner: I am lowOrderRunnerCopy the code

3. ApplicationRunner

In Spring Boot 1.3.0, an interface named ApplicationRunner was introduced along with CommandLineRunner functionality. CommandLineRunner Receive variable parameter String… Args, and ApplicationRunner receives an encapsulated object argument, ApplicationArguments. Other than that, they do exactly the same thing, even have the same method name. Declare an ApplicationRunner with the lowest priority:

package cn.felord;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;
import java.util.Set;

/** * Has the lowest priority *@author felord.cn
 * @since13:00 * * /
@Slf4j
@Component
public class DefaultApplicationRunner implements ApplicationRunner.Ordered {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("i am applicationRunner");
        Set<String> optionNames = args.getOptionNames();
        log.info("optionNames = " + optionNames);
        String[] sourceArgs = args.getSourceArgs();
        log.info("sourceArgs = " + Arrays.toString(sourceArgs));
        List<String> nonOptionArgs = args.getNonOptionArgs();
        log.info("nonOptionArgs = " + nonOptionArgs);
        List<String> optionValues = args.getOptionValues("foo");
        log.info("optionValues = " + optionValues);
    }

    @Override
    public int getOrder(a) {
        return Integer.MIN_VALUE+2; }}Copy the code

The execution results of three classes are printed in order:

The 2020-06-01 13:02:39. 19032-420 the INFO [main] C.F.M ybatisResultmapApplication: Started MybatisResultmapApplicationin1.801 seconds (JVM is runningfor2.266) the 2020-06-01 13:02:39. 19032-423 the INFO [main] C.F.H ighOrderCommandLineRunner: I am highOrderRunner 13:02:39 2020-06-01. 19032-423 the INFO [main] C.F.L owOrderCommandLineRunner: I am lowOrderRunner 13:02:39 2020-06-01. 19032-423 the INFO [main] C.F.D efaultApplicationRunner: I am applicationRunner 13:02:39 2020-06-01. 19032-423 the INFO [main] C.F.D efaultApplicationRunner: OptionNames = [] 13:02:39 2020-06-01. 19032-423 the INFO [main] C.F.D efaultApplicationRunner:sourceArgs = [] the 2020-06-01 13:02:39. 423 INFO - 19032 [main] C.F.D efaultApplicationRunner: NonOptionArgs = [] 13:02:39 2020-06-01. 19032-423 the INFO [main] C.F.D efaultApplicationRunner: optionValues = nullCopy the code

The Ordered interface cannot be replaced by the @order annotation.

4. Pass parameters

I’m sure many of you are starting to get interested in these two run methods. Spring Boot applications accept arguments when they start. In other words, Spring Boot’s main method accepts arguments. These parameters are passed on the command line java-jar yourapp.jar. CommandLineRunner takes all of these interfaces as they are, and these arguments can be wrapped into an ApplicationArguments object for ApplicationRunner to call. Let’s take a look at the methods associated with ApplicationArguments:

  • GetSourceArgs () returns an array of strings for the raw arguments passed to the application.

  • GetOptionNames () gets a Set of strings for option names. Active =dev –debug will return [“spring.profiles. Active “,”debug”].

  • GetOptionValues (String name) Obtains the option value by name. For example –foo=bar –foo=baz returns [“bar”,”baz”].

  • ContainsOption (String Name) Specifies the name of an option.

  • GetNonOptionArgs () is used to get all the optional arguments.

    For the next wave of testing, you can run a Spring Boot application Jar with the following command

Java -jar yourapp.jar --foo=bar --foo=baz --dev. Name = felordcnCopy the code

Alternatively, open Spring Boot in the IDEA development tool and apply the configuration item of the main method to perform the following configuration. The same is true for other IDE tools.

Running the Spring Boot application will print:

The 2020-06-01 15:04:31. 13208-490 the INFO [the main] C.F.H ighOrderCommandLineRunner: Arg = -- foo = 15:04:31 bar 2020-06-01. 13208-490 the INFO [main] C.F.H ighOrderCommandLineRunner: Arg = -- foo = baz 15:04:31 2020-06-01. 13208-490 the INFO [main] C.F.H ighOrderCommandLineRunner: Arg = -- dev. Name = code farmers little elder brother 15:04:31. 2020-06-01 13208-490 the INFO [main] C.F.H ighOrderCommandLineRunner: Arg = Java 15:04:31 2020-06-01. 13208-490 the INFO [main] C.F.H ighOrderCommandLineRunner: Arg = felordcn 15:04:31 2020-06-01. 13208-491 the INFO [main] C.F.H ighOrderCommandLineRunner: I am highOrderRunner 15:04:31 2020-06-01. 13208-491 the INFO [main] C.F.L owOrderCommandLineRunner: I am lowOrderRunner 15:04:31 2020-06-01. 13208-491 the INFO [main] C.F.D efaultApplicationRunner: I am applicationRunner 15:04:31 2020-06-01. 13208-491 the INFO [main] C.F.D efaultApplicationRunner: OptionNames = [dev. Name, foo] 15:04:31 2020-06-01. 13208-491 the INFO [main] C.F.D efaultApplicationRunner:sourceArgs = [--foo=bar, --foo=baz, --dev. 15:04:31 felordcn] 2020-06-01. 13208-491 the INFO [main] C.F.D efaultApplicationRunner: NonOptionArgs = [Java, felordcn] 2020-06-01 15:04:31. 13208-491 the INFO [main] C.F.D efaultApplicationRunner: optionValues = [bar, baz]Copy the code

Then you can perform some logic dynamically based on actual needs.

5. To summarize

CommandLineRunner and ApplicationRunner have been introduced and demonstrated in order to use CommandLineRunner and ApplicationRunner. More attention: code farmers xiao Pangge, more programming dry goods to share with you.

Follow our public id: Felordcn for more information

Personal blog: https://felord.cn