2015-05-19 61 views
0

我使用Spring Boot的Spring批處理,這是我的主類。無法在ItemStreamReader中的自動裝配對象打開方法

​​

這裏是我的配置類

@Configuration 
public class AppConfig { 

    @Bean 
    public MyObject getObject() { 
     return new MyObject(); 
    } 
} 

@Configuration 
@EnableBatchProcessing 
public class BatchConfiguration { 

    private static final String OVERRIDDEN_BY_EXPRESSION = null; 

    @Autowired 
    private JobBuilderFactory jobs; 

    @Autowired 
    private StepBuilderFactory steps; 

    @Bean 
    public Job job() { 
     return jobs.get(Constants.FULL_JOB_NAME) 
       .start(stepProcessDocument()) 
       .build(); 
    } 

    @Bean 
    protected Step stepProcessDocument() { 
     return steps.get(Constants.STEP_PROCESS_DOCUMENT_NAME) 
      .<Document,Document>chunk(10) 
      .reader(buildItemReader(OVERRIDDEN_BY_EXPRESSION)) 
      .processor(buildItemProcessor()) 
      .writer(buildItemWriter(OVERRIDDEN_BY_EXPRESSION)) 
      .build(); 
    } 

    @Bean 
    @StepScope 
    protected ItemReader<Document> buildItemReader(@Value("#{jobParameters[" + Constants.PARAM_JOB_PARAMETER + "]}") String param) { 
     ItemStreamReader<Document> reader = new CustomItemReader(param); 
     reader.open(new ExecutionContext()); 
     return reader; 
    } 

    @Bean 
    protected ItemProcessor<Document, Document> buildItemProcessor() { 
     return new CustomItemProcessor(); 
    } 

    @Bean 
    @StepScope 
    protected ItemWriter<Document> buildItemWriter(@Value("#{jobParameters[" + Constants.PARAM_JOB_PARAMETER + "]}") String param) { 
     ItemStreamWriter<Document> writer = new CustomItemWriter(param); 
     writer.open(new ExecutionContext()); 
     return writer; 
    } 

    @Bean 
    public JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor(JobRegistry jobRegistry) { 
     JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor = new JobRegistryBeanPostProcessor(); 
     jobRegistryBeanPostProcessor.setJobRegistry(jobRegistry); 
     return jobRegistryBeanPostProcessor; 
    } 
} 

這是我在應用程序中使用自定義的文件閱讀器。

public class CustomItemReader implements ItemStreamReader<Document> { 

@Autowired 
private MyObject myObject; 

private int count = 0; 
private String param; 

public CustomItemReader(String param) { 
    this.param = param; 
} 

@Override 
public void open(ExecutionContext executionContext) 
     throws ItemStreamException { 
    myObject.open(); //myObject is null 
} 

@Override 
public void update(ExecutionContext executionContext) 
     throws ItemStreamException { 
    // TODO Auto-generated method stub 

} 

@Override 
public void close() throws ItemStreamException { 
    myObject.close(); 
} 

@Override 
public Document read() throws Exception, UnexpectedInputException, 
     ParseException, NonTransientResourceException { 
    myObject.doStuff(); 
    count++; 
    if(count == 5) { 
     return null; 
    } 
    return new Document(); 
} 

我在myObject上得到了Java空指針異常。 爲什麼我無法在ItemStreamReader的open方法中自動裝配java對象?

+0

如何加載'Spring'上下文? – CKing

+0

你能提供'CustomFileReader'的定義嗎? –

+0

我想我得到了-1,因爲沒有足夠的信息。我爲此道歉。 – youtix

回答

1

我找到了答案。在我itemReader的定義方法:

@Bean 
@StepScope 
protected ItemReader<Document> buildItemReader(@Value("#{jobParameters[" + Constants.PARAM_JOB_PARAMETER + "]}") String param) { 
    ItemStreamReader<Document> reader = new CustomItemReader(param); 
    reader.open(new ExecutionContext()); 
    return reader; 
} 

我執行方法:

reader.open(new ExecutionContext()); 

所以每次我重新啓動它使用itemReader作業失敗,我破壞了失敗的作業步驟的執行上下文。我無法恢復我離開的地方。

要解決此問題,我必須刪除此行代碼並返回一個ItemStreamReader。從而框架可以訪問開放方法。

@Bean 
@StepScope 
protected ItemStreamReader<Document> buildItemReader(@Value("#{jobParameters[" + Constants.PARAM_JOB_PARAMETER + "]}") String param) { 
    ItemStreamReader<Document> reader = new CustomItemReader(param); 
    return reader; 
} 

此外,這個決議也解決了我原來的問題。但不幸的是,我不知道爲什麼,因爲我是Spring框架的初學者。

我希望有人能幫助我理解。

0

你需要加載Bean作爲你的環境的一部分,因爲你使用了Spring啓動時,您可以使用這樣的事情:

@EnableAutoConfiguration 
@ComponentScan 
public class Application { 

    public static void main(String[] args) throws Exception { 
     // System.exit is common for Batch applications since the exit code can be used to 
     // drive a workflow 
     System.exit(SpringApplication.exit(SpringApplication.run(
       Application.class, args))); 
    } 
} 

@ComponentScan將註冊所有的Spring組件一樣@Component, @Repository, @Service, @Controller包括@Configuration類。如果你需要看一個完整的例子看看這個項目:http://www.codingpedia.org/ama/spring-batch-tutorial-with-spring-boot-and-java-configuration/

我希望這可以是有益的。