在 Groovy 中使用 JavaConfig stepScope() 会导致 NullPointerException
Posted
技术标签:
【中文标题】在 Groovy 中使用 JavaConfig stepScope() 会导致 NullPointerException【英文标题】:Using JavaConfig stepScope() in Groovy causes NullPointerException 【发布时间】:2018-12-17 07:40:16 【问题描述】:在找到an accepted answer from a Spring Batch dev here 以及下面附带的JavaConfig 代码之后,我仍然对如何使用stepScope() 感到有些困惑。我试图在下面限定 multiResourceItemReader 的范围,但只是将 stepScope() 的 bean 定义添加到文件的顶部或底部会导致此错误:
Exception encountered during context initialization - cancelling refresh attempt:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'readFiles' defined in class path resource [com/onlinephotosubmission/csvImporter/service/BatchJobService.class]:
Bean instantiation via factory method failed;
nested exception is org.springframework.beans.BeanInstantiationException:
Failed to instantiate [java.lang.Object]: Factory method 'readFiles' threw exception;
nested exception is java.lang.NullPointerException:
Cannot invoke method get() on null object
我所知道的是 stepScope() 必须在一个 @Configuration 文件中,除此之外,我完全不知道需要做什么。
BatchJobService.groovy
@Configuration
@EnableBatchProcessing
class BatchJobService
@Autowired
JobBuilderFactory jobBuilderFactory
@Autowired
StepBuilderFactory stepBuilderFactory
@Autowired
JobLauncher jobLauncher
@Autowired
AfterJobListener afterJobListener
// Set values from properties file
@Value('$input.directory:file:inputs/*.csv')
Resource[] resources
@Value('$report.directory:output')
String reportsDir
@Value('$completed.directory:completed')
String completedDir
@Value('$report.name.prepend:people')
String prependName
@Value('$timestamp.format:dd_MM_yyyy_HH_mm_ss')
String timestampFormat
// End set properties
@Bean
StepScope stepScope()
final StepScope stepScope = new StepScope()
stepScope.setAutoProxy(true)
return stepScope
@Bean
Job readFiles()
return jobBuilderFactory
.get("readFiles")
.incrementer(new RunIdIncrementer())
.flow(step1())
.end()
.listener(afterJobListener)
.build()
@Bean
Step step1()
return stepBuilderFactory
.get("step1")
//NOTE: may need to adjust chunk size larger (say 1000 to take all transacions at once)
// or smaller (say 1 to take each transaction individually).
// Bigger is usually better, though.
.<Person, Person>chunk(1000)
.reader(multiResourceItemReader())
.processor(modifier())
.writer(writer())
.build()
@Bean
MultiResourceItemReader<Person> multiResourceItemReader()
MultiResourceItemReader<Person> resourceItemReader = new MultiResourceItemReader<Person>()
resourceItemReader.setResources(resources)
resourceItemReader.setDelegate(reader())
return resourceItemReader
@Bean
FlatFileItemReader<Person> reader()
FlatFileItemReader<Person> reader = new FlatFileItemReader<Person>()
reader.setLinesToSkip(1) //skips header line
reader.setLineMapper(new DefaultLineMapper()
setLineTokenizer(new DelimitedLineTokenizer(",")
setNames(["email", "identifier"] as String[])
)
setFieldSetMapper(new BeanWrapperFieldSetMapper<Person>() // BeanWrapperFieldSetMapper maps the line token values to a POJO directly by name
setTargetType(Person.class)
)
)
return reader
@Bean
PersonItemProcessor modifier()
return new PersonItemProcessor()
@Bean
FlatFileItemWriter<Person> writer()
FlatFileItemWriter<Person> writer = new FlatFileItemWriter<>()
writer.setAppendAllowed(true)
writer.setResource(new FileSystemResource(reportsDir + "/" + prependName + getTime() + ".csv"))
writer.setLineAggregator(new DelimitedLineAggregator<Person>()
setDelimiter(",")
setFieldExtractor(new BeanWrapperFieldExtractor<Person>()
setNames(["status", "email", "identifier"] as String[])
)
)
return writer
【问题讨论】:
【参考方案1】:@EnableBatchProcessing
自动导入StepScope
,因此您无需在应用程序上下文中将其声明为 bean。当 XML 和 Java Config 混合使用时,您链接到的问题就会发生。在您的情况下,我只看到 Java Config,所以问题不应该发生。
我正在尝试确定下面的 multiResourceItemReader 的范围
我只知道 stepScope() 必须在 @Configuration 文件中,除此之外,我完全不知道需要做什么。
仅仅声明step作用域是不够的,还需要在bean定义上加上@StepScope
注解。
您可以在此处的参考文档中找到有关 StepScope
的更多详细信息:https://docs.spring.io/spring-batch/4.0.x/reference/html/step.html#step-scope
【讨论】:
以上是关于在 Groovy 中使用 JavaConfig stepScope() 会导致 NullPointerException的主要内容,如果未能解决你的问题,请参考以下文章