diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/BatchRegistrar.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/BatchRegistrar.java
index 916ffab09..dce11d25d 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/BatchRegistrar.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/BatchRegistrar.java
@@ -22,6 +22,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.batch.core.configuration.support.AutomaticJobRegistrar;
import org.springframework.batch.core.configuration.support.DefaultJobLoader;
+import org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor;
import org.springframework.batch.core.configuration.support.MapJobRegistry;
import org.springframework.batch.core.explore.support.JobExplorerFactoryBean;
import org.springframework.batch.core.launch.support.JobOperatorFactoryBean;
@@ -61,6 +62,7 @@ class BatchRegistrar implements ImportBeanDefinitionRegistrar {
registerJobExplorer(registry, batchAnnotation);
registerJobLauncher(registry, batchAnnotation);
registerJobRegistry(registry);
+ registerJobRegistryBeanPostProcessor(registry);
registerJobOperator(registry, batchAnnotation);
registerAutomaticJobRegistrar(registry, batchAnnotation);
watch.stop();
@@ -217,6 +219,19 @@ class BatchRegistrar implements ImportBeanDefinitionRegistrar {
registry.registerBeanDefinition("jobRegistry", beanDefinition);
}
+ private void registerJobRegistryBeanPostProcessor(BeanDefinitionRegistry registry) {
+ if (registry.containsBeanDefinition("jobRegistryBeanPostProcessor")) {
+ LOGGER.info("Bean jobRegistryBeanPostProcessor already defined in the application context, skipping"
+ + " the registration of a jobRegistryBeanPostProcessor");
+ return;
+ }
+ BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder
+ .genericBeanDefinition(JobRegistryBeanPostProcessor.class);
+ beanDefinitionBuilder.addPropertyReference("jobRegistry", "jobRegistry");
+
+ registry.registerBeanDefinition("jobRegistryBeanPostProcessor", beanDefinitionBuilder.getBeanDefinition());
+ }
+
private void registerJobOperator(BeanDefinitionRegistry registry, EnableBatchProcessing batchAnnotation) {
if (registry.containsBeanDefinition("jobOperator")) {
LOGGER.info("Bean jobOperator already defined in the application context, skipping"
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.java
index 97bd6fb3c..dfeed20d5 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.java
@@ -91,6 +91,10 @@ import org.springframework.transaction.PlatformTransactionManager;
*
a {@link org.springframework.batch.core.launch.JobOperator} (bean name
* "jobOperator" of type
* {@link org.springframework.batch.core.launch.support.SimpleJobOperator})
+ * a
+ * {@link org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor}
+ * (bean name "jobRegistryBeanPostProcessor" of type
+ * {@link org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor})
*
*
* If the configuration is specified as modular=true, the context also
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/DefaultBatchConfiguration.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/DefaultBatchConfiguration.java
index dc5a18fdc..c3bdbb6e8 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/DefaultBatchConfiguration.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/DefaultBatchConfiguration.java
@@ -84,6 +84,7 @@ import org.springframework.transaction.annotation.Isolation;
* a {@link JobLauncher} named "jobLauncher"
* a {@link JobRegistry} named "jobRegistry"
* a {@link JobOperator} named "JobOperator"
+ * a {@link JobRegistryBeanPostProcessor} named "jobRegistryBeanPostProcessor"
* a {@link org.springframework.batch.core.scope.StepScope} named "stepScope"
* a {@link org.springframework.batch.core.scope.JobScope} named "jobScope"
*
@@ -208,6 +209,19 @@ public class DefaultBatchConfiguration implements ApplicationContextAware {
}
}
+ @Bean
+ public JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor() throws BatchConfigurationException {
+ JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor = new JobRegistryBeanPostProcessor();
+ jobRegistryBeanPostProcessor.setJobRegistry(jobRegistry());
+ try {
+ jobRegistryBeanPostProcessor.afterPropertiesSet();
+ return jobRegistryBeanPostProcessor;
+ }
+ catch (Exception e) {
+ throw new BatchConfigurationException("Unable to configure the default job registry BeanPostProcessor", e);
+ }
+ }
+
/*
* Getters to customize the configuration of infrastructure beans
*/
diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/BatchRegistrarTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/BatchRegistrarTests.java
index 55797db24..f26b80d3e 100644
--- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/BatchRegistrarTests.java
+++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/BatchRegistrarTests.java
@@ -27,6 +27,7 @@ import org.springframework.aop.framework.Advised;
import org.springframework.batch.core.DefaultJobKeyGenerator;
import org.springframework.batch.core.JobKeyGenerator;
import org.springframework.batch.core.configuration.JobRegistry;
+import org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.launch.JobOperator;
@@ -78,6 +79,7 @@ class BatchRegistrarTests {
Assertions.assertTrue(Mockito.mockingDetails(context.getBean(JobLauncher.class)).isMock());
Assertions.assertTrue(Mockito.mockingDetails(context.getBean(JobRegistry.class)).isMock());
Assertions.assertTrue(Mockito.mockingDetails(context.getBean(JobOperator.class)).isMock());
+ Assertions.assertTrue(Mockito.mockingDetails(context.getBean(JobRegistryBeanPostProcessor.class)).isMock());
}
@Test
@@ -160,6 +162,7 @@ class BatchRegistrarTests {
JobExplorer jobExplorer = context.getBean(JobExplorer.class);
JobRegistry jobRegistry = context.getBean(JobRegistry.class);
JobOperator jobOperator = context.getBean(JobOperator.class);
+ JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor = context.getBean(JobRegistryBeanPostProcessor.class);
// then
Assertions.assertNotNull(jobLauncher);
@@ -167,6 +170,7 @@ class BatchRegistrarTests {
Assertions.assertNotNull(jobExplorer);
Assertions.assertNotNull(jobRegistry);
Assertions.assertNotNull(jobOperator);
+ Assertions.assertNotNull(jobRegistryBeanPostProcessor);
}
@Test
@@ -244,6 +248,11 @@ class BatchRegistrarTests {
return Mockito.mock();
}
+ @Bean
+ public JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor() {
+ return Mockito.mock();
+ }
+
}
@Configuration
diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/DefaultBatchConfigurationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/DefaultBatchConfigurationTests.java
index cad911fc1..6c54df5a9 100644
--- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/DefaultBatchConfigurationTests.java
+++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/DefaultBatchConfigurationTests.java
@@ -85,6 +85,9 @@ class DefaultBatchConfigurationTests {
Assertions.assertEquals(1, jobRepositories.size());
JobRepository jobRepository = jobRepositories.entrySet().iterator().next().getValue();
Assertions.assertInstanceOf(DummyJobRepository.class, jobRepository);
+ Map jobRegistryBeanPostProcessorMap = context
+ .getBeansOfType(JobRegistryBeanPostProcessor.class);
+ Assertions.assertEquals(1, jobRegistryBeanPostProcessorMap.size());
}
@Test
@@ -98,6 +101,7 @@ class DefaultBatchConfigurationTests {
JobExplorer jobExplorer = context.getBean(JobExplorer.class);
JobRegistry jobRegistry = context.getBean(JobRegistry.class);
JobOperator jobOperator = context.getBean(JobOperator.class);
+ JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor = context.getBean(JobRegistryBeanPostProcessor.class);
// then
Assertions.assertNotNull(jobLauncher);
@@ -105,6 +109,7 @@ class DefaultBatchConfigurationTests {
Assertions.assertNotNull(jobExplorer);
Assertions.assertNotNull(jobRegistry);
Assertions.assertNotNull(jobOperator);
+ Assertions.assertNotNull(jobRegistryBeanPostProcessor);
}
@Configuration
@@ -154,6 +159,13 @@ class DefaultBatchConfigurationTests {
return new DummyJobRepository();
}
+ @Bean
+ public JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor(JobRegistry jobRegistry) {
+ JobRegistryBeanPostProcessor postProcessor = new JobRegistryBeanPostProcessor();
+ postProcessor.setJobRegistry(jobRegistry);
+ return postProcessor;
+ }
+
}
}
\ No newline at end of file
diff --git a/spring-batch-docs/modules/ROOT/pages/job/advanced-meta-data.adoc b/spring-batch-docs/modules/ROOT/pages/job/advanced-meta-data.adoc
index 6919c2f34..94fc236f5 100644
--- a/spring-batch-docs/modules/ROOT/pages/job/advanced-meta-data.adoc
+++ b/spring-batch-docs/modules/ROOT/pages/job/advanced-meta-data.adoc
@@ -222,6 +222,8 @@ example has been given an `id` so that it can be included in child
contexts (for example, as a parent bean definition) and cause all jobs created
there to also be registered automatically.
+As of version 5.1, the `@EnableBatchProcessing` annotation automatically registers a `jobRegistryBeanPostProcessor` bean in the application context.
+
[[automaticjobregistrar]]
=== AutomaticJobRegistrar