1. Введение
不知道你有没有接到这种需求,项目启动后立马执行一些逻辑。比如缓存预热,或者上线后的广播之类等等。可能现在没有但是将来会有的。想想你可能的操作, 写个接口上线我调一次行吗? НЕТ! НЕТ! НЕТ!这种初级菜鸟才干的事。今天告诉你个骚操作使得你的代码更加优雅,逼格更高。
2. Интерфейс Commandlinerunner
package org.springframework.boot;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
/**
* Interface used to indicate that a bean should <em>run</em> when it is contained within
* a {@link SpringApplication}. Multiple {@link CommandLineRunner} beans can be defined
* within the same application context and can be ordered using the {@link Ordered}
* interface or {@link Order @Order} annotation.
* <p>
* If you need access to {@link ApplicationArguments} instead of the raw String array
* consider using {@link ApplicationRunner}.
*
* @author Dave Syer
* @see ApplicationRunner
*/
@FunctionalInterface
public interface CommandLineRunner {
/**
* Callback used to run the bean.
* @param args incoming main method arguments
* @throws Exception on error
*/
void run(String... args) throws Exception;
}
CommandLineRunner
Роль заключается в том, что при запуске springApplication несколько определенных в одном и том же контексте приложенияCommandLineRunner
ТипSpring BeanВыполнить в отмеченном порядке. Если вы хотите вместо этого получить массивargs
Параметры можно заменить другим интерфейсомorg.springframework.boot.ApplicationRunner
.
talk is cheap show your codeДалее я проведу демонстрацию.
2.1 Более высокий приоритетCommandLineRunner
выполнить
package cn.felord.begin;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
/**
* 优先级比较高 通过实现接口{@link Ordered}的方式 来指定优先级
* 命令行测试参数 --foo=bar --dev.name=码农小胖哥 java,springboot
* @author Felordcn
* @since 2019/6/17 23:06
*/
@Slf4j
@Component
public class HighOrderCommandLineRunner implements CommandLineRunner , Ordered {
@Override
public void run(String... args) throws Exception {
log.info("i am highOrderRunner");
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
2.2 Более низкий приоритетCommandLineRunner
выполнить:
package cn.felord.begin;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* 优先级比较低 通过注解{@link Order}方式来指定优先级
* 比最优大64 说明会在 {@link HighOrderCommandLineRunner} 之后执行
*
* @author Felord
* @since 2019/6/17 23:07
*/
@Slf4j
@Order(Ordered.HIGHEST_PRECEDENCE + 64)
@Component
public class LowOrderCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
log.info("i am lowOrderRunner");
}
}
2.3 ИспользованиеApplicationRunner
Реализовать самый низкий приоритет:
package cn.felord.begin;
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 org.springframework.util.CollectionUtils;
import java.util.List;
/**
* 优先级最低的实现
* @author Felordcn
* @since 2019/6/18 22:13
*/
@Slf4j
@Component
public class DefaultApplicationRunner implements ApplicationRunner, Ordered {
@Override
public void run(ApplicationArguments args) throws Exception {
log.info("i am applicationRunner");
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE+65;
}
}
После запуска springboot консоль выводит результат выполнения:
2019-11-02 21:18:14.603 INFO 10244 --- [ main] c.f.begin.HighOrderCommandLineRunner : i am highOrderRunner
2019-11-02 21:18:14.604 INFO 10244 --- [ main] c.f.begin.LowOrderCommandLineRunner : i am lowOrderRunner
2019-11-02 21:18:14.604 INFO 10244 --- [ main] c.f.begin.DefaultApplicationRunner : i am applicationRunner
3. Расширенная операция - весенние загрузки, прочитанные по параметрам командной строки Начало впрыска
Для достижения желаемых результатов мы начали с. Так в чем же разница между этими двумя интерфейсами?SpringЧиновник не наестся и не имеет отношения к двум подбрасывателям, должна быть разница, по методу интерфейсаrun
Из метода видно, что параметры разные, дополнительные научно-популярныеSpring BootКак передать дополнительные аргументы для выполнения через командную строкуjava -jarПерейти кmainметод, правила следующие
- Ключевое значение отформатировано
--K=V
Разделяйте несколько пробелами - Значение, разделенное несколькими пробелами
Откройте элемент конфигурации основного метода в инструменте разработки идей и выполните следующую настройку.То же самое верно и для других инструментов IDE. Содержимое параметра:--foo=bar --dev.name=код фермер маленький толстый брат java springboot
HighOrderCommandLineRunner
распечатать этоargs
параметр:
package cn.felord.begin;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
/**
* 优先级比较高 通过实现接口{@link Ordered}的方式 来指定优先级
* 命令行测试参数 --foo=bar --dev.name=码农小胖哥 java,springboot
* @author dax
* @since 2019/6/17 23:06
*/
@Slf4j
@Component
public class HighOrderCommandLineRunner implements CommandLineRunner , Ordered {
@Override
public void run(String... args) throws Exception {
for (String arg : args) {
System.out.println("arg = " + arg);
}
log.info("i am highOrderRunner");
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
потомDefaultApplicationRunner
изApplicationArguments
Также смотрим:
package cn.felord.begin;
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 org.springframework.util.CollectionUtils;
import java.util.List;
/**
* @author Felord
* @since 2019/6/18 22:13
*/
@Slf4j
@Component
public class DefaultApplicationRunner implements ApplicationRunner, Ordered {
@Override
public void run(ApplicationArguments args) throws Exception {
log.info("i am applicationRunner");
args.getOptionNames().forEach(System.out::println);
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>");
String[] sourceArgs = args.getSourceArgs();
if (sourceArgs!=null){
for (String sourceArg : sourceArgs) {
System.out.println("sourceArg = " + sourceArg);
}
}
System.out.println("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
List<String> foo = args.getOptionValues("foo");
if (!CollectionUtils.isEmpty(foo)){
foo.forEach(System.out::println);
}
System.out.println("++++++++++++");
List<String> nonOptionArgs = args.getNonOptionArgs();
System.out.println("nonOptionArgs.size() = " + nonOptionArgs.size());
nonOptionArgs.forEach(System.out::println);
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE+65;
}
}
Начать сначалаSpring BootКонсоль выводит результат:
arg = --foo=bar
arg = --dev.name=码农小胖哥
arg = java
arg = springboot
2019-11-02 21:18:14.603 INFO 10244 --- [ main] c.f.begin.HighOrderCommandLineRunner : i am highOrderRunner
2019-11-02 21:18:14.604 INFO 10244 --- [ main] c.f.begin.LowOrderCommandLineRunner : i am lowOrderRunner
2019-11-02 21:18:14.604 INFO 10244 --- [ main] c.f.begin.DefaultApplicationRunner : i am applicationRunner
dev.name
foo
>>>>>>>>>>>>>>>>>>>>>>>>>>
sourceArg = --foo=bar
sourceArg = --dev.name=码农小胖哥
sourceArg = java
sourceArg = springboot
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
bar
++++++++++++
nonOptionArgs.size() = 2
java
springboot
Мы обнаружили, что можем использовать эти два интерфейса для чтенияSpring Bootаргументы командной строки. На самом деле, мы также можем использовать@Value
Аннотацию читать, здесь не поясняется, если интересно, можете попробовать сами. сюдаApplicationRunner
иCommandLineRunner
Разница очевидна из консоли.
4. ApplicationRunner
иCommandLineRunner
разница
сверхуlogмы знаемarg=
заCommandLineRunner
изargs
数组打印,仅仅单纯把上面的参数以空格为规则解析成了原汁原味的数组。 иApplicationRunner
является более изысканным. Узнай, распечатавApplicationArguments
Предоставляет несколько полезных методов разбора параметров:
-
args.getOptionNames()
это получить пару ключ-значение--K=V
серединаK
-
args.getOptionValues("foo")
раньше проходилK
чтобы получить значение пары ключ-значениеV
-
args.getSourceArgs()
ЭквивалентноCommandLineRunner
изargs
множество -
args.getNonOptionArgs()
Худшее использовалось, чтобы получить одну собаку
Предостережение заключается в том, чтобы иметь дело с нулевыми указателями при разборе ApplicationArguments.
5. Резюме
Сегодня мы проходимCommandLineRunner
иApplicationRunner
объяснять. Как решитьSpring BootПроблема выполнения некоторой логики при запуске и расстановка приоритетов логики множественного запуска. В то же время мы делаем шаг вперед и читаем эти два метода.Spring BootПараметр запуска. А затем также выяснил тонкие различия между двумя интерфейсами. Надеюсь, это поможет вам.
关注公众号:Felordcn获取更多资讯