Add a JobRegistryBeanPostProcessor in the default batch configuration

Resolves #4245
This commit is contained in:
Mahmoud Ben Hassine
2023-09-11 13:51:05 +02:00
parent df4bf84688
commit 70e8a1c497
6 changed files with 56 additions and 0 deletions

View File

@@ -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"

View File

@@ -91,6 +91,10 @@ import org.springframework.transaction.PlatformTransactionManager;
* <li>a {@link org.springframework.batch.core.launch.JobOperator} (bean name
* "jobOperator" of type
* {@link org.springframework.batch.core.launch.support.SimpleJobOperator})</li>
* <li>a
* {@link org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor}
* (bean name "jobRegistryBeanPostProcessor" of type
* {@link org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor})</li>
* </ul>
*
* If the configuration is specified as <code>modular=true</code>, the context also

View File

@@ -84,6 +84,7 @@ import org.springframework.transaction.annotation.Isolation;
* <li>a {@link JobLauncher} named "jobLauncher"</li>
* <li>a {@link JobRegistry} named "jobRegistry"</li>
* <li>a {@link JobOperator} named "JobOperator"</li>
* <li>a {@link JobRegistryBeanPostProcessor} named "jobRegistryBeanPostProcessor"</li>
* <li>a {@link org.springframework.batch.core.scope.StepScope} named "stepScope"</li>
* <li>a {@link org.springframework.batch.core.scope.JobScope} named "jobScope"</li>
* </ul>
@@ -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
*/

View File

@@ -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

View File

@@ -85,6 +85,9 @@ class DefaultBatchConfigurationTests {
Assertions.assertEquals(1, jobRepositories.size());
JobRepository jobRepository = jobRepositories.entrySet().iterator().next().getValue();
Assertions.assertInstanceOf(DummyJobRepository.class, jobRepository);
Map<String, JobRegistryBeanPostProcessor> 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;
}
}
}

View File

@@ -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