我已经创建了带有 Spring 云任务的 Spring 启动应用程序,该任务应该执行一些命令(任务)。
每个任务/命令都是短期任务,所有任务都从命令行开始,执行一些简短的ETL作业并完成执行。
有一个包含所有命令/任务的spring boot jar。
每个任务都是CommandLineRunner,我想根据命令行中的参数来决定执行哪些任务(一个或多个)。
最佳做法是什么?
我不喜欢有肮脏的代码问“如果不是”或类似的东西。
最佳答案
Spring Boot从应用程序上下文运行所有CommandLineRunner
或ApplicationRunner
Bean。您不能通过任何参数选择一个。
因此,基本上,您有两种可能性:
CommandLineRunner
实现,并且在每个实现中都检查参数以确定是否应运行此特殊的CommandLineRunner
。 CommandLineRunner
。代码可能看起来像这样:这是运行者将实现的新接口(interface):
public interface MyCommandLineRunner {
void run(String... strings) throws Exception;
}
然后,您定义实现并用名称标识它们:
@Component("one")
public class MyCommandLineRunnerOne implements MyCommandLineRunner {
private static final Logger log = LoggerFactory.getLogger(MyCommandLineRunnerOne.class);
@Override
public void run(String... strings) throws Exception {
log.info("running");
}
}
和
@Component("two")
public class MyCommandLineRunnerTwo implements MyCommandLineRunner {
private static final Logger log = LoggerFactory.getLogger(MyCommandLineRunnerTwo.class);
@Override
public void run(String... strings) throws Exception {
log.info("running");
}
}
然后在单个
CommandLineRunner
实现中,您将掌握应用程序上下文并按名称解析所需的bean,我的示例仅使用第一个参数,并将其称为MyCommandLineRunner.run()
方法:@Component
public class CommandLineRunnerImpl implements CommandLineRunner, ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void run(String... strings) throws Exception {
if (strings.length < 1) {
throw new IllegalArgumentException("no args given");
}
String name = strings[0];
final MyCommandLineRunner myCommandLineRunner = applicationContext.getBean(name, MyCommandLineRunner.class);
myCommandLineRunner.run(strings);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}