[英]Custom ItemReader with spring-data-jpa
I'm creating a Spring batch project using existing entities and repositories. 我正在使用现有实体和存储库创建Spring批处理项目。 I need to use custom
ItemReader
for the job which reads data using the existing jpa repositories. 我需要使用自定义
ItemReader
作为使用现有jpa存储库读取数据的作业。
Custom reader 定制读者
public class InMemoryReader implements ItemReader<Product> {
@Autowired
private ProductService productService;
private int nextStudentIndex;
private List<Product> studentData;
public InMemoryReader() {
initialize();
}
private void initialize() {
studentData = new ArrayList<Product>();
studentData.add(new Product("hi"));
for (Product p : productService.get())
studentData.add(p);
nextStudentIndex = 0;
}
@Override
public Product read() throws Exception {
Product nextStudent = null;
if (nextStudentIndex < studentData.size()) {
nextStudent = studentData.get(nextStudentIndex);
nextStudentIndex++;
}
return nextStudent;
}
}
But I can't Autowire the ProductService
in the itemreader
. 但我不能在
ProductService
中自动itemreader
ProductService
。 It throwing error as follows: 它抛出错误如下:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'reader' defined in class path resource [wariyum/sb/emailNotifier/BatchConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.batch.item.ItemReader]: Factory method 'reader' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:305)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:834)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:689)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:969)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:958)
at wariyum.sb.emailNotifier.Application.main(Application.java:15)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.batch.item.ItemReader]: Factory method 'reader' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
... 16 common frames omitted
Caused by: java.lang.NullPointerException: null
at wariyum.sb.emailNotifier.service.InMemoryReader.initialize(InMemoryReader.java:31)
at wariyum.sb.emailNotifier.service.InMemoryReader.<init>(InMemoryReader.java:24)
at wariyum.sb.emailNotifier.BatchConfiguration.reader(BatchConfiguration.java:41)
at wariyum.sb.emailNotifier.BatchConfiguration$$EnhancerBySpringCGLIB$$df186b4e.CGLIB$reader$0(<generated>)
at wariyum.sb.emailNotifier.BatchConfiguration$$EnhancerBySpringCGLIB$$df186b4e$$FastClassBySpringCGLIB$$724d6a16.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:318)
at wariyum.sb.emailNotifier.BatchConfiguration$$EnhancerBySpringCGLIB$$df186b4e.reader(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
... 17 common frames omitted
Batch configuration file 批量配置文件
@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
private DataSource dataSource;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Bean
public ItemReader<Product> reader() throws Exception {
return new InMemoryReader();
}
@Bean
public ProductItemProcessor processor() {
return new ProductItemProcessor();
}
@Bean
public ItemWriter<Product> writer() {
return new ItemWriter<Product>() {
@Override
public void write(List<? extends Product> items) throws Exception {
}
};
}
// end::readerwriterprocessor[]
// tag::listener[]
@Bean
public JobExecutionListener listener() {
return null;
}
// end::listener[]
// tag::jobstep[]
@Bean
public Job importPerson(JobBuilderFactory jobs, Step s1) {
return jobs.get("import")
.incrementer(new RunIdIncrementer()) // because a spring config bug, this incrementer is not really useful
.flow(s1)
.end()
.build();
}
@Bean
public Step step1() throws Exception {
return stepBuilderFactory.get("step1")
.<Product, Product>chunk(10)
.reader(reader())
.processor(processor())
.writer(writer())
.build();
}
}
Product service implementation 产品服务实施
@Service("productService")
public class ProductServiceImpl implements ProductService {
private ProductRepository repository;
@Autowired
public ProductServiceImpl(ProductRepository repository) {
this.repository = repository;
}
@Override
public List<Product> get() {
List<Product> list = new ArrayList<Product>();
for (Product p : repository.findAll())
list.add(p);
return list;
}
}
You are calling initialize()
from the constructor ie before the ProductService
dependency has been wired. 您正在从构造函数中调用
initialize()
,即在连接ProductService
依赖项之前。
Remove the call to initialize()
from the constructor and instead have Spring invoke it after the dependencies have been wired by annotating it with @PostConstruct
or using one of the other methods outlined here: 从构造函数中删除对
initialize()
的调用,然后让Spring通过使用@PostConstruct
或使用此处概述的其他方法之一来连接依赖项之后调用它:
How to call a method after bean initialization is complete? bean初始化完成后如何调用方法?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.