Как выполнить часть логики сразу после запуска приложения Spring Boot

Spring Boot Java

1. Введение

Не знаю, получали ли вы такой запрос, но выполняйте какую-то логику сразу после старта проекта. Например, простой прогрев кеша, или трансляция после выхода в интернет и т.п. если вы используетеSpring BootФреймворк может использовать предоставляемый им интерфейсCommandLineRunnerиApplicationRunnerреализовать.

2. CommandLineRunner

org.springframework.boot.CommandLineRunnerдаSpring BootПредоставляет интерфейс, когда вы реализуете интерфейс и вводите егоSpring IoCПосле контейнера,Spring BootКогда приложение запускается, оно выполняет своюrunметод. ОдинSpring Bootможет быть несколькоCommandLineRunnerреализация, когда их несколько, вы можете реализоватьOrderedИнтерфейс управляет порядком выполнения этих реализаций (Чем выше стоимость заказа, тем ниже приоритет). Затем мы объявляем две реализации и указываем порядок:

Приоритетное исполнение:

package cn.felord;

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

/**
 * 优先级最高
 * 该类期望在springboot 启动后第一顺位执行
 * @author felord.cn
 * @since 12: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() {
        return Integer.MIN_VALUE+1;
    }
}

Выполнение второго заказа:

package cn.felord;

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

/**
 * 优先级低于{@code HighOrderCommandLineRunner}
 * @author felord.cn
 * @since 12:59
 **/
@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() {
        return Integer.MIN_VALUE+1;
    }
}

затем начнитеSpring BootПосле применения консоль выводит результаты в заданном порядке:

2020-05-30 23:11:03.685  INFO 11976 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2020-05-30 23:11:03.701  INFO 11976 --- [           main] c.f.Application  : Started SpringBootApplication in 4.272 seconds (JVM running for 6.316)
2020-05-30 23:11:03.706  INFO 11976 --- [           main] c.f.HighOrderCommandLineRunner   : i am highOrderRunner
2020-05-30 23:11:03.706  INFO 11976 --- [           main] c.f.LowOrderCommandLineRunner   : i am lowOrderRunner

3. ApplicationRunner

существуетSpring Boot 1.3.0представил еще один иCommandLineRunnerфункционально тот же интерфейсApplicationRunner.CommandLineRunnerполучать переменные аргументыString... argsApplicationRunnerПолучает параметр инкапсулированного объектаApplicationArguments. В остальном они работают точно так же, даже имена методов одинаковы. объявить одинApplicationRunnerи сделать его самым низким приоритетом:

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;

/**
 * 优先级最低
 * @author felord.cn
 * @since 13: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() {
        return Integer.MIN_VALUE+2;
    }
}

Результаты выполнения трех классов выводятся по порядку:

2020-06-01 13:02:39.420  INFO 19032 --- [           main] c.f.MybatisResultmapApplication  : Started MybatisResultmapApplication in 1.801 seconds (JVM running for 2.266)
2020-06-01 13:02:39.423  INFO 19032 --- [           main] c.f.HighOrderCommandLineRunner   : i am highOrderRunner
2020-06-01 13:02:39.423  INFO 19032 --- [           main] c.f.LowOrderCommandLineRunner    : i am lowOrderRunner
2020-06-01 13:02:39.423  INFO 19032 --- [           main] c.f.DefaultApplicationRunner     : i am applicationRunner
2020-06-01 13:02:39.423  INFO 19032 --- [           main] c.f.DefaultApplicationRunner     : optionNames = []
2020-06-01 13:02:39.423  INFO 19032 --- [           main] c.f.DefaultApplicationRunner     : sourceArgs = []
2020-06-01 13:02:39.423  INFO 19032 --- [           main] c.f.DefaultApplicationRunner     : nonOptionArgs = []
2020-06-01 13:02:39.423  INFO 19032 --- [           main] c.f.DefaultApplicationRunner     : optionValues = null

Orderedинтерфейс не может быть@Orderвместо аннотаций.

4. Передать параметры

Я полагаю, что многие студенты видят здесь и начинают думать об этих двухrunМеня интересуют параметры метода.Spring BootКогда приложение запускается, оно может принимать параметры, другими словами,Spring BootизmainМетоды могут принимать параметры. Эти параметры передаются через командную строкуjava -jar yourapp.jar передавать.CommandLineRunnerЭти интерфейсы будут получены как есть, и эти параметры также могут быть инкапсулированы вApplicationArgumentsобъект дляApplicationRunnerперечислить. будем знакомыApplicationArgumentsСвязанный метод:

  • getSourceArgs()Необработанные параметры, переданные приложению, возвращают массив строк этих параметров.

  • getOptionNames()получить имя опцииSetКоллекция строк. как--spring.profiles.active=dev --debugвернусь["spring.profiles.active","debug"].

  • getOptionValues(String name)Получить значение параметра, соответствующее имени по имени. как--foo=bar --foo=bazвернусь["bar","baz"].

  • containsOption(String name)Имя, используемое для определения того, включена ли опция.

  • getNonOptionArgs()Используется для получения всех аргументов, не являющихся параметрами.

    Далее давайте попробуем волну, вы можете запуститьSpring BootприменениеJar

java -jar yourapp.jar --foo=bar --foo=baz --dev.name=码农小胖哥 java felordcn

или вIDEAоткрыть в инструментах разработчикаSpring BootприменениеmainЭлемент конфигурации метода настраивается следующим образом, остальныеIDEИнструменты те же.

бегатьSpring BootПримените, он распечатает:

2020-06-01 15:04:31.490  INFO 13208 --- [           main] c.f.HighOrderCommandLineRunner   : arg = --foo=bar
2020-06-01 15:04:31.490  INFO 13208 --- [           main] c.f.HighOrderCommandLineRunner   : arg = --foo=baz
2020-06-01 15:04:31.490  INFO 13208 --- [           main] c.f.HighOrderCommandLineRunner   : arg = --dev.name=码农小胖哥
2020-06-01 15:04:31.490  INFO 13208 --- [           main] c.f.HighOrderCommandLineRunner   : arg = java
2020-06-01 15:04:31.490  INFO 13208 --- [           main] c.f.HighOrderCommandLineRunner   : arg = felordcn
2020-06-01 15:04:31.491  INFO 13208 --- [           main] c.f.HighOrderCommandLineRunner   : i am highOrderRunner
2020-06-01 15:04:31.491  INFO 13208 --- [           main] c.f.LowOrderCommandLineRunner    : i am lowOrderRunner
2020-06-01 15:04:31.491  INFO 13208 --- [           main] c.f.DefaultApplicationRunner     : i am applicationRunner
2020-06-01 15:04:31.491  INFO 13208 --- [           main] c.f.DefaultApplicationRunner     : optionNames = [dev.name, foo]
2020-06-01 15:04:31.491  INFO 13208 --- [           main] c.f.DefaultApplicationRunner     : sourceArgs = [--foo=bar, --foo=baz, --dev.name=码农小胖哥, java, felordcn]
2020-06-01 15:04:31.491  INFO 13208 --- [           main] c.f.DefaultApplicationRunner     : nonOptionArgs = [java, felordcn]
2020-06-01 15:04:31.491  INFO 13208 --- [           main] c.f.DefaultApplicationRunner     : optionValues = [bar, baz]

Затем вы можете выполнять некоторую логику динамически по мере необходимости.

5. Резюме

Сегодня мыCommandLineRunnerиApplicationRunnerОбъяснение, от использования до последовательного выполнения, иSpring BootПередача параметров введена и продемонстрирована, я надеюсь помочь вам. Уделять больше внимания:Код Фермер Маленький Толстый Брат, больше программирования галантереи, чтобы поделиться с вами.

关注公众号:Felordcn获取更多资讯

Личный блог: https://felord.cn