title: Spring Batch: MultiResourcePartitioner how to set resources lazily
body: <p><strong><em>Question:</em></strong> How to set/Inject resources lazily like how it is done using the XML config in Java config.</p>
  
  <p>We have spring batch program that is currently using XML configuration for uploading multiple files using the <code>MultiResourcePartitioner</code>. This works as intended see below config.</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;beans  xmlns="http://www.springframework.org/schema/beans"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:batch="http://www.springframework.org/schema/batch"
         xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-3.0.xsd"&gt;
  
      &lt;job id="fileLoaderJob" xmlns="http://www.springframework.org/schema/batch"&gt;
  
          &lt;step id="moveFiles" next="batchFileUploader"&gt;
              &lt;tasklet ref="moveFilesTasklet" /&gt;          
          &lt;/step&gt;
  
          &lt;step id="batchFileUploader" parent="batchFileUpload:master" &gt;
              &lt;next on="*" to="archiveFiles" /&gt;
          &lt;/step&gt;
  
          &lt;step id="archiveFiles" &gt;
              &lt;batch:tasklet ref="archiveFilesTasklet" /&gt;         
          &lt;/step&gt;
  
      &lt;/job&gt;
  
      &lt;!--This Tasklet moves the file from say Input to Work dir --&gt;
      &lt;bean id="moveFilesTasklet" class="com.spring.batch.fileloader.MoveFilesTasklet" scope="step" /&gt;
  
      &lt;step id="batchFileUpload" xmlns="http://www.springframework.org/schema/batch"&gt;
          &lt;tasklet&gt;
              &lt;chunk reader="fileReader"      
                     commit-interval="10000"
                     writer="fileWriter"
              /&gt;
          &lt;/tasklet&gt;
      &lt;/step&gt;
  
      &lt;bean name="batchFileUpload:master" class="org.springframework.batch.core.partition.support.PartitionStep"&gt;
          &lt;property name="jobRepository" ref="jobRepository"/&gt;
          &lt;property name="stepExecutionSplitter"&gt;
              &lt;bean class="org.springframework.batch.core.partition.support.SimpleStepExecutionSplitter"&gt;
                  &lt;constructor-arg ref="jobRepository"/&gt;
                  &lt;constructor-arg ref="batchFileUpload"/&gt;
                  &lt;constructor-arg&gt;
                      &lt;bean class="org.springframework.batch.core.partition.support.MultiResourcePartitioner" scope="step"&gt;
                          &lt;property name="resources" ref="fileResources" /&gt;
                      &lt;/bean&gt;
                  &lt;/constructor-arg&gt;
              &lt;/bean&gt;
          &lt;/property&gt; 
          &lt;property name="partitionHandler"&gt;
              &lt;bean class="org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler"&gt;
                  &lt;property name="taskExecutor"&gt;
                      &lt;bean class="org.springframework.core.task.SimpleAsyncTaskExecutor"&gt;
                          &lt;property name="concurrencyLimit" value="5" /&gt;
                      &lt;/bean&gt;
                  &lt;/property&gt;
                  &lt;property name="step" ref="batchFileUpload"/&gt;
              &lt;/bean&gt;
          &lt;/property&gt;
      &lt;/bean&gt;
  
      &lt;bean id="fileResources" class="com.spring.batch.fileloader.fileResources" /&gt;
  
      &lt;bean id="fileReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step"&gt;
          &lt;property name="resource" value="#{stepExecutionContext[fileName]}" /&gt;
          &lt;property name="lineMapper"&gt;
              &lt;bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper"&gt;
                  &lt;property name="lineTokenizer"&gt;
                      &lt;bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer"&gt;
                          &lt;property name="delimiter" value="," /&gt;
                      &lt;/bean&gt;
                  &lt;/property&gt;
                  &lt;property name="fieldSetMapper"&gt;
                      &lt;bean class="...fileFieldSetMapper" /&gt;
                  &lt;/property&gt;
              &lt;/bean&gt;
          &lt;/property&gt;
      &lt;/bean&gt;
  
      &lt;bean id="fileWriter" class="....fileWriter" scope="step" /&gt;
  
      &lt;bean id="archiveFilesTasklet" class="....ArchiveFilesTasklet" scope="step" /&gt;  
  
  &lt;/beans&gt;
  </code></pre>
  
  <p>This works well. When I try to covert this to Java Config. I am getting the resources as <code>NULL</code>.  Here is my config class.</p>
  
  <pre><code>@Configuration
  @EnableBatchProcessing
  @ComponentScan(basePackages = {"com.spring.batch.fileloader"})
  public class SpringBatchConfig{
  
      @Autowired
      private JobBuilderFactory jobBuilders;
  
      @Autowired
      private StepBuilderFactory stepBuilders;
  
      @Autowired
      private DataSource dataSource;
  
      @Autowired
      private ResourcePatternResolver resourcePatternResolver;
  
      @Autowired
      private ReadPropertiesFile properties;
  
      @Bean
      BatchConfigurer configurer(@Qualifier("dataSource") DataSource dataSource){
          return new DefaultBatchConfigurer(dataSource);
      }
  
      @Bean(name = "fileLoaderJob")
      public Job csiAuditFileLoaderJob() throws Exception{
          return jobBuilders.get("csiAuditFileLoaderJob")
                  .start(moveFiles())
                  .next(batchFileUploader())
                  .next(archiveFiles())
                  .build();
      }
  
      @Bean
      public Step moveFiles(){
          return stepBuilders.get("moveFiles")
                  .tasklet(new MoveFilesTasklet(properties))
                  .build();
      }
  
      @Bean
      @Lazy
      public Step batchFileUploader() throws Exception{
          return stepBuilders.get("batchFileUploader")
                  .partitioner(batchFileUploadStep().getName(), partitioner())
                  .step(batchFileUploadStep())
                  .taskExecutor(taskExecutor())
                  .build();
      }
  
      @Bean
      public Step archiveFiles(){
          return stepBuilders.get("archiveFiles")
                  .tasklet(new ArchiveFilesTasklet(properties))
                  .build();
      }
  
      @Bean
      public Step batchFileUploadStep(){
          return stepBuilders.get("batchFileUploadStep")
                  .&lt;MyDomain, MyDomain&gt;chunk(10000)
                  .reader(fileReader(null))
                  .writer(fileWriter())
                  .build();
      }
  
      @Bean
      @Lazy
      public Partitioner partitioner() throws Exception{
  
          MultiResourcePartitioner partitioner = new MultiResourcePartitioner();
  
          Resource[] resources;
          try{
              /*
              Here the resources is selected from a path where the previous MoveFilesTasklet moves the file
              This returns null since Spring Initialize this bean eagerly before the step is called for execution.
              */
              resources = resourcePatternResolver.getResources("file:" + properties.getPath() + "/*.csv");
          }
          catch(IOException e){
              throw new RuntimeException("I/O problems when resolving the input file pattern.", e);
          }
  
          partitioner.setResources(resources);
          return partitioner;
      }
  
      @Bean
      public TaskExecutor taskExecutor(){
          ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
          taskExecutor.setMaxPoolSize(5);
          taskExecutor.afterPropertiesSet();
          return taskExecutor;
      }
  
      @Bean
      @StepScope
      public FlatFileItemReader&lt;MyDomain&gt; fileReader(
              @Value("#{stepExecutionContext['fileName']}") String filename){
          FlatFileItemReader&lt;MyDomain&gt; reader = new FlatFileItemReader&lt;&gt;();
          DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
          DefaultLineMapper&lt;MyDomain&gt; lineMapper = new DefaultLineMapper&lt;&gt;();
          lineMapper.setLineTokenizer(tokenizer);
          lineMapper.setFieldSetMapper(new MyFieldSetMapper());
          lineMapper.afterPropertiesSet();
  
          reader.setLineMapper(lineMapper);
          reader.setResource(new PathResource(filename));
  
          return reader;
      }
  
      @Bean
      public ItemWriter&lt;MyDomain&gt; fileWriter(){
          return new FileWriter();
      }
  
  
      private JobRepository getJobRepository() throws Exception{
          JobRepositoryFactoryBean jobRepositoryFactoryBean = new JobRepositoryFactoryBean();
          jobRepositoryFactoryBean.setDataSource(dataSource);
          jobRepositoryFactoryBean.setTransactionManager(getTransactionManager());
          jobRepositoryFactoryBean.setDatabaseType("MySql");
          jobRepositoryFactoryBean.afterPropertiesSet();
          return jobRepositoryFactoryBean.getObject();
      }
  
      private PlatformTransactionManager getTransactionManager(){
          return new ResourcelessTransactionManager();
      }
  
      @Bean
      public JobLauncher jobLauncher() throws Exception{
          SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
          jobLauncher.setJobRepository(getJobRepository());
          jobLauncher.afterPropertiesSet();
          return jobLauncher;
      }
  
  }
  </code></pre>