Skip to content

Commit

Permalink
Supports modularized job configuration like @EnableBatchProcessing(mo…
Browse files Browse the repository at this point in the history
…dular=true)
  • Loading branch information
quaff committed Jul 4, 2023
1 parent cc23029 commit 4434be8
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,16 @@

import javax.sql.DataSource;

import org.springframework.batch.core.configuration.BatchConfigurationException;
import org.springframework.batch.core.configuration.JobRegistry;
import org.springframework.batch.core.configuration.ListableJobLocator;
import org.springframework.batch.core.configuration.StepRegistry;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.support.ApplicationContextFactory;
import org.springframework.batch.core.configuration.support.AutomaticJobRegistrar;
import org.springframework.batch.core.configuration.support.DefaultBatchConfiguration;
import org.springframework.batch.core.configuration.support.DefaultJobLoader;
import org.springframework.batch.core.configuration.support.JobLoader;
import org.springframework.batch.core.converter.JobParametersConverter;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.batch.core.launch.JobLauncher;
Expand Down Expand Up @@ -66,6 +73,7 @@
* @author Eddú Meléndez
* @author Kazuki Shimizu
* @author Mahmoud Ben Hassine
* @author Yanming Zhou
* @since 1.0.0
*/
@AutoConfiguration(after = { HibernateJpaAutoConfiguration.class, TransactionAutoConfiguration.class })
Expand Down Expand Up @@ -162,6 +170,28 @@ protected ConfigurableConversionService getConversionService() {

}

@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(prefix = "spring.batch.job", name = "modular", havingValue = "true")
static class SpringBootBatchModularConfiguration {

@Bean
public JobLoader jobLoader(JobRegistry jobRegistry, ObjectProvider<StepRegistry> stepRegistry) {
DefaultJobLoader jobLoader = new DefaultJobLoader(jobRegistry);
stepRegistry.ifAvailable(jobLoader::setStepRegistry);
return jobLoader;
}

@Bean
public AutomaticJobRegistrar automaticJobRegistrar(JobLoader jobLoader,
ObjectProvider<ApplicationContextFactory> applicationContextFactories) {
AutomaticJobRegistrar automaticJobRegistrar = new AutomaticJobRegistrar();
automaticJobRegistrar.setJobLoader(jobLoader);
applicationContextFactories.forEach(automaticJobRegistrar::addApplicationContextFactory);
return automaticJobRegistrar;
}

}

@Configuration(proxyBeanMethods = false)
@Conditional(OnBatchDatasourceInitializationCondition.class)
static class DataSourceInitializerConfiguration {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,12 @@
"description": "Execute all Spring Batch jobs in the context on startup.",
"defaultValue": true
},
{
"name": "spring.batch.job.modular",
"type": "java.lang.Boolean",
"description": "Whether the job configuration is going to be modularized like @EnableBatchProcessing(modular=true)",
"defaultValue": false
},
{
"name": "spring.batch.schema",
"type": "java.lang.String",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@
import org.springframework.batch.core.configuration.JobFactory;
import org.springframework.batch.core.configuration.JobRegistry;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.support.ApplicationContextFactory;
import org.springframework.batch.core.configuration.support.DefaultBatchConfiguration;
import org.springframework.batch.core.configuration.support.GenericApplicationContextFactory;
import org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.batch.core.job.AbstractJob;
Expand Down Expand Up @@ -93,6 +95,7 @@
* @author Stephane Nicoll
* @author Vedran Pavic
* @author Kazuki Shimizu
* @author Yanming Zhou
*/
@ExtendWith(OutputCaptureExtension.class)
class BatchAutoConfigurationTests {
Expand Down Expand Up @@ -422,6 +425,19 @@ void conversionServiceCustomizersAreCalled() {
});
}

@Test
void testModular() {
this.contextRunner.withUserConfiguration(ModularConfiguration.class, EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.batch.job.modular=true")
.run((context) -> {
JobRegistry jobRegistry = context.getBean(JobRegistry.class);
assertThat(jobRegistry.getJobNames()).containsExactlyInAnyOrder("job", "discreteLocalJob");
context.getBean(JobLauncher.class).run(jobRegistry.getJob("discreteLocalJob"), new JobParameters());
assertThat(context.getBean(JobRepository.class)
.getLastJobExecution("discreteLocalJob", new JobParameters())).isNotNull();
});
}

@Configuration(proxyBeanMethods = false)
protected static class BatchDataSourceConfiguration {

Expand Down Expand Up @@ -719,4 +735,19 @@ BatchConversionServiceCustomizer anotherBatchConversionServiceCustomizer() {

}

@Configuration(proxyBeanMethods = false)
static class ModularConfiguration {

@Bean
ApplicationContextFactory jobConfiguration() {
return new GenericApplicationContextFactory(JobConfiguration.class);
}

@Bean
ApplicationContextFactory namedJobConfigurationWithLocalJob() {
return new GenericApplicationContextFactory(NamedJobConfigurationWithLocalJob.class);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Spring Batch auto-configuration is enabled by adding `spring-boot-starter-batch`
If a single `Job` is found in the application context, it is executed on startup (see {spring-boot-autoconfigure-module-code}/batch/JobLauncherApplicationRunner.java[`JobLauncherApplicationRunner`] for details).
If multiple `Job` beans are found, the job that should be executed must be specified using configprop:spring.batch.job.name[].

To disable running a `Job` found in the application context, set the configprop:spring.batch.job.enabled[] to `false.`
To disable running a `Job` found in the application context, set the configprop:spring.batch.job.enabled[] to `false`.

See {spring-boot-autoconfigure-module-code}/batch/BatchAutoConfiguration.java[BatchAutoConfiguration] for more details.

Expand Down Expand Up @@ -60,3 +60,28 @@ This provides only one argument to the batch job: `someParameter=someValue`.
Spring Batch requires a data store for the `Job` repository.
If you use Spring Boot, you must use an actual database.
Note that it can be an in-memory database, see {spring-batch-docs}job.html#configuringJobRepository[Configuring a Job Repository].



[[howto.batch.modularizing-job-configuration]]
=== Modularizing Job Configuration
To modularize job configuration into multiple application contexts, set the configprop:spring.batch.job.modular[] to `true`,
and supply them in separate (child) contexts through {spring-batch-api}/core/configuration/support/ApplicationContextFactory.html[`ApplicationContextFactory`].

[source,java,indent=0,subs="verbatim"]
----
@Configuration(proxyBeanMethods = false)
static class ModularBatchConfiguration {
@Bean
ApplicationContextFactory job1Configuration() {
return new GenericApplicationContextFactory(Job1Configuration.class);
}
@Bean
ApplicationContextFactory job2Configuration() {
return new GenericApplicationContextFactory(Job2Configuration.class);
}
}
----

0 comments on commit 4434be8

Please sign in to comment.