【问题标题】:How to load a Spring Configuration based on a command line argument?如何基于命令行参数加载 Spring 配置?
【发布时间】:2020-04-28 07:49:12
【问题描述】:

我有几个不同的@Configuration 类,每个类对应一个不同的 Spring Batch 作业,即每个配置中存在一个 Job bean,并且给定作业所需的每个 Step、Tasklet 等都存在于相同的配置中类作为那个工作。示例:

@Configuration
public class DemoJobConfiguration(JobBuilderFactory jobBuilderFactory) {
    @Bean
    public Job demoJob() {
        return jobBuilderFactory.get("demoJob").start(...).build();
    }
}

@Configuration
public class TestJobConfiguration(JobBuilderFactory jobBuilderFactory) {
    @Bean
    public Job testJob() {
        return jobBuilderFactory.get("testJob").start(...).build();
    }
}

该应用程序是一个命令行应用程序。第一个参数是要运行的作业的名称。根据该参数检索关联的 Job bean,然后使用 JobLauncher 执行。示例:

@Override
public void run(String... args) throws Exception {
    String jobName = args[0];
    Job job = prepareJob(jobName); //gets the Job from the application context
    JobParameters jobParameters = prepareJobParameters(args); //sets args[1], etc. to JobParameter objects
    JobExecution result = jobLauncher.run(job, jobParameters);
}

我想知道的是,如果 args[0] 是某个值,例如,是否有一种方法可以使用 @Conditional 注释(或其他东西)仅加载配置类,例如,

@Configuration
@Conditional("\"testJob\".equals(args[0])")
public class TestJobConfiguration(JobBuilderFactory jobBuilderFactory) {
    ...
}

这样做的好处是,只有与正在运行的作业相关的 bean 才会被加载到内存中,而与其他作业对应的 bean 永远不会被加载。随着更多工作被添加到项目中,这将非常有帮助。

是否可以基于命令行参数加载配置?以前做过吗?一个小时的谷歌搜索没有出现任何结果,但我仍然希望有办法实现这一点。

【问题讨论】:

    标签: java spring-boot configuration spring-batch applicationcontext


    【解决方案1】:

    我想出了自己问题的答案。

    解决方案:

    1. 以 --jobName=testJob 的形式包含命令行参数。 Spring boot 会自动将其加载到环境中 (https://docs.spring.io/spring-boot/docs/1.0.1.RELEASE/reference/html/boot-features-external-config.html)

    2. 像这样使用@ConditonalOnProperty 注解:

      @ConditionalOnProperty(value = "jobName", havingValue = "testJob") 公共类 TestJobConfiguration { ... }

    【讨论】:

      【解决方案2】:

      如果您想根据命令行参数更好地控制条件配置,您可以创建一个自定义Condition,它可以使用ApplicationArguments 类来完全解析选项:

      public class CustomCommandLineArgsCondition implements Condition {
      
          @Override
          public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
              ApplicationArguments args = context.getBeanFactory().getBean(ApplicationArguments.class);
      
              //Do something with the command line arguments.
              return true;
          }
      }
      

      然后你用@Conditional(CustomCommandLineArgsCondition.class)注释你的配置类

      【讨论】:

        猜你喜欢
        • 2016-04-21
        • 2017-11-12
        • 1970-01-01
        • 2012-07-12
        • 1970-01-01
        • 2020-11-27
        • 2015-12-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多