【问题标题】:Could not autowired Object in ItemStreamReader open method无法在 ItemStreamReader 打开方法中自动装配对象
【发布时间】:2015-07-31 14:11:31
【问题描述】:

我在 Spring Boot 中使用 Spring Batch,这是我的主要课程。

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

这是我的配置类

@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 对象?

【问题讨论】:

  • 如何加载Spring 上下文?
  • 你能提供CustomFileReader的定义吗?
  • 我想我得到了-1,因为没有足够的信息。对此我深表歉意。

标签: java spring spring-batch reader


【解决方案1】:

你需要加载你的 Beans 作为你的上下文的一部分,因为你使用的是 Spring Boot,你可以使用这样的东西:

@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/

我希望这会有所帮助。

【讨论】:

    【解决方案2】:

    我找到了答案。在我的 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。因此框架可以访问 open 方法。

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

    此外,这个解决方案也解决了我原来的问题。但不幸的是,我不知道为什么,因为我是 Spring Framework 的初学者。

    希望有人能帮助我理解。

    【讨论】:

      猜你喜欢
      • 2012-01-27
      • 1970-01-01
      • 2013-11-12
      • 2016-08-03
      • 1970-01-01
      • 2019-05-08
      • 1970-01-01
      • 1970-01-01
      • 2016-10-09
      相关资源
      最近更新 更多