2015-05-19 65 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/

我希望这可以是有益的。