我已经创建了带有 Spring 云任务的 Spring 启动应用程序,该任务应该执行一些命令(任务)。
每个任务/命令都是短期任务,所有任务都从命令行开始,执行一些简短的ETL作业并完成执行。

有一个包含所有命令/任务的spring boot jar。
每个任务都是CommandLineRunner,我想根据命令行中的参数来决定执行哪些任务(一个或多个)。
最佳做法是什么?
我不喜欢有肮脏的代码问“如果不是”或类似的东西。

最佳答案

Spring Boot从应用程序上下文运行所有CommandLineRunnerApplicationRunner 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;
        }
    }
    

    08-05 15:36