Reputation: 61
I have a few different @Configuration classes, each of which corresponds to a different Spring Batch job, i.e., one Job bean exists in each configuration and each Step, Tasklet, etc. required for a given job exists in the same configuration class as that job. Example:
@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();
}
}
The application is a command-line application. The first argument is the name of the job to run. The associated Job bean is retrieved based on that argument and then is executed with a JobLauncher. Example:
@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);
}
What I'd like to know is if there's a way to use a @Conditional annotation (or something else) to only load a configuration class if args[0] is a certain value, e.g.,
@Configuration
@Conditional("\"testJob\".equals(args[0])")
public class TestJobConfiguration(JobBuilderFactory jobBuilderFactory) {
...
}
The advantage to this would be that only beans relevant to the job being run are ever loaded into memory and beans corresponding to other jobs are never loaded. This would be majorly helpful as more jobs get added to the project.
Is loading configurations based on command line arguments possible? Has it been done before? An hour of googling didn't turn up anything but I'm still hopeful that there's a way to accomplish this.
Upvotes: 3
Views: 2967
Reputation: 2015
If you want more control over Conditional Configuration based on Command Line arguments you can create a custom Condition that can use the the ApplicationArguments class to fully parse the Options:
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;
}
}
You then annotate your configuration class with @Conditional(CustomCommandLineArgsCondition.class)
Upvotes: 0
Reputation: 61
I figured out the answer to my own question.
Solution:
Include a command line argument in the form --jobName=testJob. Spring boot will automatically load that into the Environment (https://docs.spring.io/spring-boot/docs/1.0.1.RELEASE/reference/html/boot-features-external-config.html)
Use the @ConditonalOnProperty annotation like so:
@ConditionalOnProperty(value = "jobName", havingValue = "testJob") public class TestJobConfiguration { ... }
Upvotes: 3