Spring Batch 2.2 – JavaConfig Part 5: Modular configurations

29.6.2013 | 2 minutes of reading time

When adding more jobs to an ApplicationContext, you will soon run into problems with the naming and the uniqueness of beans. Normally you define one configuration class or one configuration XML file for each job, and then it feels natural to name the ItemReader reader. When adding both configurations to the ApplicationContext, we have two beans with the same name – reader. If we’re lucky, we get an Exception when starting the ApplicationContext, if we’re not they silently override each other. How can we deal with this problem?
This is the fifth post about the new Java based configuration features in Spring Batch 2.2. Previous posts are about a comparison between the new Java DSL and XML , JobParameters, ExecutionContexts and StepScope , profiles and environments and job inheritance . Future posts will be about partitioning and multi-threaded step , everything regarding Java based configuration, of course. You can find the JavaConfig code examples on Github .

The solution to this problem is the following construct:
Instead of having just one ApplicationContext we have one for each job, this way we have no problems with bean naming or overriding. The infrastructure part resides in a common parent ApplicationContext, and we access jobs via the JobRegistry defined in the parent context.

Let’s have a look at a modular job configuration:

3public class ModularJobConfiguration {
5    @Bean
6    public DataSource dataSource(){
7        EmbeddedDatabaseBuilder embeddedDatabaseBuilder = new EmbeddedDatabaseBuilder();
8        return embeddedDatabaseBuilder.addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql")
9                .addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql")
10                .addScript("classpath:schema-partner.sql")
11                .setType(EmbeddedDatabaseType.HSQL)
12                .build();
13    }
15    @Bean
16    public ApplicationContextFactory someJobs() {
17        return new GenericApplicationContextFactory(FlatfileToDbJobConfiguration.class);
18    }
20    @Bean
21    public ApplicationContextFactory someMoreJobs() {
22        return new GenericApplicationContextFactory(FlatfileToDbWithParametersJobConfiguration.class);
23    }

This way an AutomaticJobRegistrar is added to the ApplicationContext which is responsible for creating separate ApplicationContexts for each bean of type ApplicationContextFactory. So we have two jobs registered in two different client ApplicationContexts. We can access them with the JobRegistry:

3public class ModularJobTests {
5    @Autowired
6    private JobRegistry jobRegistry;
8    @Autowired
9    private JobLauncher jobLauncher;
11    @Autowired
12    private DataSource dataSource;
14    private JdbcTemplate jdbcTemplate;
16    @Before
17    public void setup(){
18        jdbcTemplate = new JdbcTemplate(dataSource);
19    }
21    @Test
22    public void testLaunchJob() throws Exception {
23        Job job = jobRegistry.getJob("flatfileToDbJob");
24        jobLauncher.run(job, new JobParameters());
25        assertThat(jdbcTemplate.queryForObject("select count(*) from partner",Integer.class),is(6));
26        job = jobRegistry.getJob("flatfileToDbWithParametersJob");
27        assertThat(job.getName(),is("flatfileToDbWithParametersJob"));
28    }


If you want to separate jobs in different contexts so that they don’t interfere with each other, make use of this modular configuration feature.

share post




Gemeinsam bessere Projekte umsetzen

Wir helfen Deinem Unternehmen

Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.

Hilf uns, noch besser zu werden.

Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.