Make MapJobRegistry smart to auto register jobs at startup

Before this commit, it was required to populate the job registry
with a different component (like a bean post processor or a smart
initializing singleton) before being able to use it with the JobOperator.

This commit makes the `MapJobRegistry` smart enough to auto register
jobs defined in the application context. This removes the need for a
distinct component to populate the registry and therefore simplifies
the configuration.

This commit also:

- removes the usage of `JobFactory` from `JobRegistry`
- deprecates JobRegistrySmartInitializingSingleton and removes
its configuration from the default batch configuration

Resolves #4854
Resolves #4855
Resolves #4856
This commit is contained in:
Mahmoud Ben Hassine
2025-06-02 16:29:09 +02:00
parent 08c4cb16b8
commit a7f090a45d
18 changed files with 87 additions and 234 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2022 the original author or authors.
* Copyright 2006-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,17 +22,18 @@ import org.springframework.batch.core.Job;
* <code>name</code>.
*
* @author Dave Syer
* @author Mahmoud Ben Hassine
*
*/
public interface JobRegistry extends ListableJobLocator {
/**
* Registers a {@link Job} at runtime.
* @param jobFactory the {@link Job} to be registered
* @throws DuplicateJobException if a factory with the same job name has already been
* @param job the {@link Job} to be registered
* @throws DuplicateJobException if a job with the same name has already been
* registered.
*/
void register(JobFactory jobFactory) throws DuplicateJobException;
void register(Job job) throws DuplicateJobException;
/**
* Unregisters a previously registered {@link Job}. If it was not previously

View File

@@ -22,7 +22,6 @@ 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.JobRegistrySmartInitializingSingleton;
import org.springframework.batch.core.configuration.support.MapJobRegistry;
import org.springframework.batch.core.launch.support.JobOperatorFactoryBean;
import org.springframework.batch.core.repository.support.JdbcJobRepositoryFactoryBean;
@@ -70,7 +69,6 @@ class BatchRegistrar implements ImportBeanDefinitionRegistrar {
.synthesize();
registerJobRepository(registry, importingClassMetadata);
registerJobRegistry(registry);
registerJobRegistrySmartInitializingSingleton(registry);
registerJobOperator(registry, batchAnnotation);
registerAutomaticJobRegistrar(registry, batchAnnotation);
watch.stop();
@@ -220,21 +218,6 @@ class BatchRegistrar implements ImportBeanDefinitionRegistrar {
registry.registerBeanDefinition(JOB_REGISTRY, beanDefinition);
}
private void registerJobRegistrySmartInitializingSingleton(BeanDefinitionRegistry registry) {
if (registry.containsBeanDefinition("jobRegistrySmartInitializingSingleton")) {
LOGGER
.info("Bean jobRegistrySmartInitializingSingleton already defined in the application context, skipping"
+ " the registration of a jobRegistrySmartInitializingSingleton");
return;
}
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder
.genericBeanDefinition(JobRegistrySmartInitializingSingleton.class);
beanDefinitionBuilder.addPropertyReference(JOB_REGISTRY, JOB_REGISTRY);
registry.registerBeanDefinition("jobRegistrySmartInitializingSingleton",
beanDefinitionBuilder.getBeanDefinition());
}
private void registerJobOperator(BeanDefinitionRegistry registry, EnableBatchProcessing batchAnnotation) {
if (registry.containsBeanDefinition(JOB_OPERATOR)) {
LOGGER.info("Bean jobOperator already defined in the application context, skipping"

View File

@@ -50,8 +50,6 @@ import org.springframework.transaction.annotation.Isolation;
* <li>a {@link ResourcelessJobRepository} named "jobRepository"</li>
* <li>a {@link MapJobRegistry} named "jobRegistry"</li>
* <li>a {@link TaskExecutorJobOperator} named "JobOperator"</li>
* <li>a {@link JobRegistrySmartInitializingSingleton} named
* "jobRegistrySmartInitializingSingleton"</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>
@@ -117,21 +115,6 @@ public class DefaultBatchConfiguration implements ApplicationContextAware {
}
}
@Bean
public JobRegistrySmartInitializingSingleton jobRegistrySmartInitializingSingleton(JobRegistry jobRegistry)
throws BatchConfigurationException {
JobRegistrySmartInitializingSingleton jobRegistrySmartInitializingSingleton = new JobRegistrySmartInitializingSingleton();
jobRegistrySmartInitializingSingleton.setJobRegistry(jobRegistry);
try {
jobRegistrySmartInitializingSingleton.afterPropertiesSet();
return jobRegistrySmartInitializingSingleton;
}
catch (Exception e) {
throw new BatchConfigurationException(
"Unable to configure the default job registry SmartInitializingSingleton", e);
}
}
/**
* Return the transaction manager to use for the job operator. Defaults to
* {@link ResourcelessTransactionManager}.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2023 the original author or authors.
* Copyright 2006-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,7 +27,6 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.DuplicateJobException;
import org.springframework.batch.core.configuration.JobFactory;
import org.springframework.batch.core.configuration.JobRegistry;
import org.springframework.batch.core.configuration.StepRegistry;
import org.springframework.batch.core.launch.NoSuchJobException;
@@ -251,8 +250,7 @@ public class DefaultJobLoader implements JobLoader, InitializingBean {
* @throws DuplicateJobException if that job is already registered
*/
private void doRegister(ConfigurableApplicationContext context, Job job) throws DuplicateJobException {
final JobFactory jobFactory = new ReferenceJobFactory(job);
jobRegistry.register(jobFactory);
jobRegistry.register(job);
if (stepRegistry != null) {
if (!(job instanceof StepLocator)) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2023 the original author or authors.
* Copyright 2006-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@ import org.springframework.batch.core.configuration.JobRegistry;
* Generic service that can bind and unbind a {@link JobFactory} in a {@link JobRegistry}.
*
* @author Dave Syer
* @author Mahmoud Ben Hassine
*
*/
public class JobFactoryRegistrationListener {
@@ -53,7 +54,7 @@ public class JobFactoryRegistrationListener {
if (logger.isInfoEnabled()) {
logger.info("Binding JobFactory: " + jobFactory.getJobName());
}
jobRegistry.register(jobFactory);
jobRegistry.register(jobFactory.createJob());
}
/**

View File

@@ -45,7 +45,10 @@ import org.springframework.util.Assert;
*
* @author Henning Pöttker
* @since 5.1.1
* @deprecated since 6.0 with no replacement. Register a {@link MapJobRegistry} as a bean,
* and it will automatically register all {@link Job} beans in the application context.
*/
@Deprecated(since = "6.0", forRemoval = true)
public class JobRegistrySmartInitializingSingleton
implements SmartInitializingSingleton, BeanFactoryAware, InitializingBean, DisposableBean {
@@ -143,12 +146,11 @@ public class JobRegistrySmartInitializingSingleton
groupName = getGroupName(defaultListableBeanFactory.getBeanDefinition(beanName), job);
}
job = groupName == null ? job : new GroupAwareJob(groupName, job);
ReferenceJobFactory jobFactory = new ReferenceJobFactory(job);
String name = jobFactory.getJobName();
String name = job.getName();
if (logger.isDebugEnabled()) {
logger.debug("Registering job: " + name);
}
jobRegistry.register(jobFactory);
jobRegistry.register(job);
jobNames.add(name);
}
catch (DuplicateJobException e) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2019 the original author or authors.
* Copyright 2006-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,68 +16,89 @@
package org.springframework.batch.core.configuration.support;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.configuration.DuplicateJobException;
import org.springframework.batch.core.configuration.JobFactory;
import org.springframework.batch.core.configuration.JobRegistry;
import org.springframework.batch.core.launch.NoSuchJobException;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Simple, thread-safe, map-based implementation of {@link JobRegistry}.
* Simple, thread-safe, map-based implementation of {@link JobRegistry}. This registry is
* a {@link SmartInitializingSingleton} that is automatically populated with all
* {@link Job} beans in the {@link ApplicationContext}.
*
* @author Dave Syer
* @author Robert Fischer
* @author Mahmoud Ben Hassine
*/
public class MapJobRegistry implements JobRegistry {
public class MapJobRegistry implements JobRegistry, SmartInitializingSingleton, ApplicationContextAware {
protected final Log logger = LogFactory.getLog(getClass());
/**
* The map holding the registered job factories.
* The map holding the registered jobs.
*/
// The "final" ensures that it is visible and initialized when the constructor
// resolves.
private final ConcurrentMap<String, JobFactory> map = new ConcurrentHashMap<>();
private final ConcurrentMap<String, Job> map = new ConcurrentHashMap<>();
private ApplicationContext applicationContext;
@Override
public void register(JobFactory jobFactory) throws DuplicateJobException {
Assert.notNull(jobFactory, "jobFactory is null");
String name = jobFactory.getJobName();
Assert.notNull(name, "Job configuration must have a name.");
JobFactory previousValue = map.putIfAbsent(name, jobFactory);
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public void afterSingletonsInstantiated() {
Map<String, Job> jobBeans = this.applicationContext.getBeansOfType(Job.class);
this.map.putAll(jobBeans);
}
@Override
public void register(Job job) throws DuplicateJobException {
Assert.notNull(job, "job must not be null");
String jobName = job.getName();
Assert.notNull(jobName, "Job name must not be null");
Job previousValue = this.map.putIfAbsent(jobName, job);
if (previousValue != null) {
throw new DuplicateJobException("A job configuration with this name [" + name + "] was already registered");
throw new DuplicateJobException("A job with this name [" + jobName + "] was already registered");
}
}
@Override
public void unregister(String name) {
Assert.notNull(name, "Job configuration must have a name.");
map.remove(name);
Assert.notNull(name, "Job name must not be null");
this.map.remove(name);
}
@Override
public Job getJob(@Nullable String name) throws NoSuchJobException {
JobFactory factory = map.get(name);
if (factory == null) {
throw new NoSuchJobException("No job configuration with the name [" + name + "] was registered");
Job job = this.map.get(name);
if (job == null) {
throw new NoSuchJobException("No job with the name [" + name + "] was registered");
}
else {
return factory.createJob();
return job;
}
}
/**
* Provides an unmodifiable view of the job names.
* Provides an unmodifiable view of job names.
*/
@Override
public Set<String> getJobNames() {
return Collections.unmodifiableSet(map.keySet());
return Collections.unmodifiableSet(this.map.keySet());
}
}

View File

@@ -27,7 +27,6 @@ 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.JobRegistrySmartInitializingSingleton;
import org.springframework.batch.core.converter.DefaultJobParametersConverter;
import org.springframework.batch.core.converter.JobParametersConverter;
import org.springframework.batch.core.converter.JsonJobParametersConverter;
@@ -64,8 +63,6 @@ class BatchRegistrarTests {
Assertions.assertTrue(Mockito.mockingDetails(context.getBean(JobRepository.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(JobRegistrySmartInitializingSingleton.class)).isMock());
}
@Test
@@ -147,15 +144,12 @@ class BatchRegistrarTests {
JobRepository jobRepository = context.getBean(JobRepository.class);
JobRegistry jobRegistry = context.getBean(JobRegistry.class);
JobOperator jobOperator = context.getBean(JobOperator.class);
JobRegistrySmartInitializingSingleton jobRegistrySmartInitializingSingleton = context
.getBean(JobRegistrySmartInitializingSingleton.class);
// then
Assertions.assertNotNull(jobLauncher);
Assertions.assertNotNull(jobRepository);
Assertions.assertNotNull(jobRegistry);
Assertions.assertNotNull(jobOperator);
Assertions.assertNotNull(jobRegistrySmartInitializingSingleton);
}
@Test
@@ -236,11 +230,6 @@ class BatchRegistrarTests {
return Mockito.mock();
}
@Bean
public JobRegistrySmartInitializingSingleton jobRegistrySmartInitializingSingleton() {
return Mockito.mock();
}
}
@Configuration

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2022-2024 the original author or authors.
* Copyright 2022-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,7 +36,6 @@ import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -72,9 +71,6 @@ class DefaultBatchConfigurationTests {
Assertions.assertEquals(1, jobRepositories.size());
JobRepository jobRepository = jobRepositories.entrySet().iterator().next().getValue();
Assertions.assertInstanceOf(DummyJobRepository.class, jobRepository);
Map<String, JobRegistrySmartInitializingSingleton> jobRegistrySmartInitializingSingletonMap = context
.getBeansOfType(JobRegistrySmartInitializingSingleton.class);
Assertions.assertEquals(1, jobRegistrySmartInitializingSingletonMap.size());
}
@Test
@@ -87,15 +83,12 @@ class DefaultBatchConfigurationTests {
JobRepository jobRepository = context.getBean(JobRepository.class);
JobRegistry jobRegistry = context.getBean(JobRegistry.class);
JobOperator jobOperator = context.getBean(JobOperator.class);
JobRegistrySmartInitializingSingleton jobRegistrySmartInitializingSingleton = context
.getBean(JobRegistrySmartInitializingSingleton.class);
// then
Assertions.assertNotNull(jobLauncher);
Assertions.assertNotNull(jobRepository);
Assertions.assertNotNull(jobRegistry);
Assertions.assertNotNull(jobOperator);
Assertions.assertNotNull(jobRegistrySmartInitializingSingleton);
}
@Configuration
@@ -136,13 +129,6 @@ class DefaultBatchConfigurationTests {
return new DummyJobRepository();
}
@Bean
public JobRegistrySmartInitializingSingleton jobRegistrySmartInitializingSingleton(JobRegistry jobRegistry) {
JobRegistrySmartInitializingSingleton smartInitializingSingleton = new JobRegistrySmartInitializingSingleton();
smartInitializingSingleton.setJobRegistry(jobRegistry);
return smartInitializingSingleton;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2022 the original author or authors.
* Copyright 2006-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,9 +20,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.configuration.JobFactory;
import org.springframework.batch.core.test.repository.JobSupport;
/**
* @author Dave Syer
* @author Mahmoud Ben Hassine
*
*/
class JobFactoryRegistrationListenerTests {
@@ -37,7 +39,7 @@ class JobFactoryRegistrationListenerTests {
listener.bind(new JobFactory() {
@Override
public Job createJob() {
return null;
return new JobSupport("foo");
}
@Override
@@ -54,7 +56,7 @@ class JobFactoryRegistrationListenerTests {
listener.unbind(new JobFactory() {
@Override
public Job createJob() {
return null;
return new JobSupport("foo");
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2022 the original author or authors.
* Copyright 2006-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
/**
* @author Dave Syer
* @author Mahmoud Ben Hassine
*
*/
@SpringJUnitConfig

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2024 the original author or authors.
* Copyright 2024-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,11 +26,9 @@ import org.springframework.batch.core.configuration.JobRegistry;
import org.springframework.batch.core.job.JobSupport;
import org.springframework.beans.FatalBeanException;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.lenient;
@@ -95,28 +93,4 @@ class JobRegistrySmartInitializingSingletonTests {
assertTrue(jobRegistry.getJobNames().isEmpty());
}
@Test
void testExecutionWithApplicationContext() throws Exception {
var context = new ClassPathXmlApplicationContext("test-context-with-smart-initializing-singleton.xml",
getClass());
var registry = context.getBean("registry", JobRegistry.class);
Collection<String> jobNames = registry.getJobNames();
String[] names = context.getBeanNamesForType(JobSupport.class);
int count = names.length;
// Each concrete bean of type JobConfiguration is registered...
assertEquals(count, jobNames.size());
// N.B. there is a failure / wonky mode where a parent bean is given an
// explicit name or beanName (using property setter): in this case then
// child beans will have the same name and will be re-registered (and
// override, if the registry supports that).
assertNotNull(registry.getJob("test-job"));
assertEquals(context.getBean("test-job-with-name"), registry.getJob("foo"));
assertEquals(context.getBean("test-job-with-bean-name"), registry.getJob("bar"));
assertEquals(context.getBean("test-job-with-parent-and-name"), registry.getJob("spam"));
assertEquals(context.getBean("test-job-with-parent-and-bean-name"), registry.getJob("bucket"));
assertEquals(context.getBean("test-job-with-concrete-parent"), registry.getJob("maps"));
assertEquals(context.getBean("test-job-with-concrete-parent-and-name"), registry.getJob("oof"));
assertEquals(context.getBean("test-job-with-concrete-parent-and-bean-name"), registry.getJob("rab"));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2022 the original author or authors.
* Copyright 2006-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,21 +15,19 @@
*/
package org.springframework.batch.core.configuration.support;
import java.util.Collection;
import org.junit.jupiter.api.Test;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.configuration.DuplicateJobException;
import org.springframework.batch.core.configuration.JobFactory;
import org.springframework.batch.core.job.JobSupport;
import org.springframework.batch.core.launch.NoSuchJobException;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.Collection;
import static org.junit.jupiter.api.Assertions.*;
/**
* @author Dave Syer
* @author Mahmoud Ben Hassine
*
*/
class MapJobRegistryTests {
@@ -38,7 +36,7 @@ class MapJobRegistryTests {
@Test
void testUnregister() throws Exception {
registry.register(new ReferenceJobFactory(new JobSupport("foo")));
registry.register(new JobSupport("foo"));
assertNotNull(registry.getJob("foo"));
registry.unregister("foo");
Exception exception = assertThrows(NoSuchJobException.class, () -> registry.getJob("foo"));
@@ -47,28 +45,30 @@ class MapJobRegistryTests {
@Test
void testReplaceDuplicateConfiguration() throws Exception {
registry.register(new ReferenceJobFactory(new JobSupport("foo")));
JobFactory jobFactory = new ReferenceJobFactory(new JobSupport("foo"));
Exception exception = assertThrows(DuplicateJobException.class, () -> registry.register(jobFactory));
registry.register(new JobSupport("foo"));
Job job = new JobSupport("foo");
Exception exception = assertThrows(DuplicateJobException.class, () -> registry.register(job));
assertTrue(exception.getMessage().contains("foo"));
}
@Test
void testRealDuplicateConfiguration() throws Exception {
JobFactory jobFactory = new ReferenceJobFactory(new JobSupport("foo"));
registry.register(jobFactory);
Exception exception = assertThrows(DuplicateJobException.class, () -> registry.register(jobFactory));
Job job = new JobSupport("foo");
registry.register(job);
Exception exception = assertThrows(DuplicateJobException.class, () -> registry.register(job));
assertTrue(exception.getMessage().contains("foo"));
}
@Test
void testGetJobConfigurations() throws Exception {
JobFactory jobFactory = new ReferenceJobFactory(new JobSupport("foo"));
registry.register(jobFactory);
registry.register(new ReferenceJobFactory(new JobSupport("bar")));
Job job1 = new JobSupport("foo");
Job job2 = new JobSupport("bar");
registry.register(job1);
registry.register(job2);
Collection<String> configurations = registry.getJobNames();
assertEquals(2, configurations.size());
assertTrue(configurations.contains(jobFactory.getJobName()));
assertTrue(configurations.contains(job1.getName()));
assertTrue(configurations.contains(job2.getName()));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2022 the original author or authors.
* Copyright 2013-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -13,10 +13,6 @@
<bean id="jobRegistry" class="org.springframework.batch.core.configuration.support.MapJobRegistry"/>
<bean class="org.springframework.batch.core.configuration.support.JobRegistrySmartInitializingSingleton">
<property name="jobRegistry" ref="jobRegistry"/>
</bean>
<batch:job-repository id="jobRepository" table-prefix="BATCH_"/>
<bean id="jobExplorer" class="org.springframework.batch.core.repository.explore.support.JobExplorerFactoryBean">

View File

@@ -1,76 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean
class="org.springframework.batch.core.configuration.support.JobRegistrySmartInitializingSingleton">
<property name="jobRegistry" ref="registry" />
</bean>
<bean id="registry"
class="org.springframework.batch.core.configuration.support.MapJobRegistry" />
<bean id="test-job"
class="org.springframework.batch.core.job.JobSupport">
<property name="steps">
<bean id="step1" class="org.springframework.batch.core.step.factory.SimpleStepFactoryBean">
<property name="itemReader" ref="itemReader" />
<property name="itemWriter" ref="itemWriter" />
<property name="jobRepository" ref="jobRepository" />
<property name="transactionManager" ref="transactionManager"/>
</bean>
</property>
</bean>
<bean id="itemReader"
class="org.springframework.batch.item.support.ListItemReader">
<constructor-arg value="foo,bar,spam" />
</bean>
<bean id="itemWriter"
class="org.springframework.batch.core.launch.EmptyItemWriter" />
<bean id="jobRepository"
class="org.springframework.batch.core.step.JobRepositorySupport" />
<bean id="transactionManager"
class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
<bean id="test-job-with-name"
class="org.springframework.batch.core.job.JobSupport">
<property name="name" value="foo" />
</bean>
<bean id="test-job-with-bean-name"
class="org.springframework.batch.core.job.JobSupport">
<property name="beanName" value="bar" />
</bean>
<bean id="abstract-job"
class="org.springframework.batch.core.job.JobSupport"
abstract="true" />
<bean id="test-job-with-parent" parent="abstract-job" />
<bean id="test-job-with-parent-and-name" parent="abstract-job"
p:name="spam" />
<bean id="test-job-with-parent-and-bean-name" parent="abstract-job"
p:name="bucket" />
<bean id="parent-job"
class="org.springframework.batch.core.job.JobSupport" />
<bean id="test-job-with-concrete-parent" parent="parent-job"
p:name="maps" />
<bean id="test-job-with-concrete-parent-and-name"
parent="parent-job" p:name="oof" />
<bean id="test-job-with-concrete-parent-and-bean-name"
parent="parent-job" p:beanName="rab" />
</beans>

View File

@@ -19,10 +19,6 @@
<bean id="jobRegistry"
class="org.springframework.batch.core.configuration.support.MapJobRegistry" />
<bean
class="org.springframework.batch.core.configuration.support.JobRegistrySmartInitializingSingleton">
<property name="jobRegistry" ref="jobRegistry" />
</bean>
<batch:job id="job2">
<batch:step id="j2.s1" parent="step1" />

View File

@@ -38,8 +38,4 @@
<bean id="jobRegistry" class="org.springframework.batch.core.configuration.support.MapJobRegistry"/>
<bean class="org.springframework.batch.core.configuration.support.JobRegistrySmartInitializingSingleton">
<property name="jobRegistry" ref="jobRegistry"/>
</bean>
</beans>