gpt4 book ai didi

java - Spring Boot + Spring Batch + @StepScope = 没有代理 Bean?

转载 作者:搜寻专家 更新时间:2023-11-01 03:19:31 31 4
gpt4 key购买 nike

我目前正在为应用程序设置文件导入服务,允许用户通过 REST 上传 csv 文件。根据 future 的处理要求和检查,作业的导入将通过 Spring Batch 完成,因为这些作业可能会长时间运行。

根据我的说法,以下设置对于 Spring Boot 和 Spring Batch 是正确的,但代码无法编译。

主要的 BatchConfiguration 文件:

@Configuration
@EnableBatchProcessing
public class PatientBatchConfiguration {

@Autowired
private JobBuilderFactory jobBuilders;

@Autowired
private StepBuilderFactory stepBuilders;

@Autowired
private PatientFieldSetMapper fieldSetMapper;

@Autowired
private PatientItemWriter writer;

@Bean
public Job importPatientsFromUpload(){
return jobBuilders.get("importPatientsFromUpload")
.start(step())
.build();
}

@Bean
public Step step(){
return stepBuilders.get("step")
.<Patient,Patient>chunk(1)
.reader(reader(null))
.writer(writer)
.build();
}

@Bean
@StepScope
public ItemReader<Patient> reader(@Value("#{jobParameters['fileName']}") String filePath) {
FlatFileItemReader<Patient> itemReader = new FlatFileItemReader<Patient>();
itemReader.setLineMapper(lineMapper());
itemReader.setResource(new FileSystemResource(filePath));
return itemReader;
}

private LineMapper<Patient> lineMapper() {
DefaultLineMapper<Patient> lineMapper = new DefaultLineMapper<Patient>();
DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();
lineTokenizer.setNames(new String[]{"name","surname","idNumber","dob", "email", "cell"});
lineMapper.setLineTokenizer(lineTokenizer);
lineMapper.setFieldSetMapper(fieldSetMapper);
return lineMapper;
}

}

FieldSetMapper代码:

@Component
public class PatientFieldSetMapper implements FieldSetMapper<Patient> {

@Override
public Patient mapFieldSet(FieldSet fieldSet) throws BindException {

if(fieldSet == null){
return null;
}

Patient patient = new Patient();
patient.setName(fieldSet.readString("name"));
patient.setSurname(fieldSet.readString("surname"));
patient.setIdNo(fieldSet.readString("idNumber"));
patient.setDob(0L);
patient.setEmail(fieldSet.readString("email"));
patient.setCell(fieldSet.readString("cell"));

return patient;
}
}

PatientItemWriter 代码:

@Component
public class PatientItemWriter implements ItemWriter<Patient> {

@Autowired
PatientRepository patientRepository;

@Override
public void write(List<? extends Patient> list) throws Exception {

for(Patient patient: list) {
patientRepository.save(patient);
}
}
}

堆栈跟踪:

Caused by: java.lang.IllegalArgumentException: Path must not be null
at org.springframework.util.Assert.notNull(Assert.java:115) ~[spring-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.core.io.FileSystemResource.<init>(FileSystemResource.java:75) ~[spring-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at com.example.batch.patient.PatientBatchConfiguration.reader(PatientBatchConfiguration.java:59) ~[classes/:na]
at com.example.batch.patient.PatientBatchConfiguration.step(PatientBatchConfiguration.java:49) ~[classes/:na]

最后是 application.properties 文件

spring.batch.job.enabled=false

spring.batch.job.enabled=false 位于属性文件中的原因是,作业 importPatientsFromUpload 将在用户上传文件后从 Controller 调用,如果没有它,作业将在启动时运行。

我遇到的问题是无法创建 FileSystemResource,因为路径不能为空。但是我知道,一旦有人用@StepScope 注释一个方法,就会创建一个代理 bean,这将允许我使用在运行时传递的 jobParameter 来创建一个新的文件系统资源。我在网上看到过各种以这种方式使用 jobParameters 的例子,但由于某种原因,bean 似乎没有被正确创建。我不确定这是否与我使用的是 Spring Boot 或其他一些错误有关。

如有任何帮助,我们将不胜感激。提前致谢。

更新回复 Gaël

PatientItemReader 代码:

@Component
@StepScope
public class PatientItemReader implements ItemReader<Patient> {

@Autowired
private PatientFieldSetMapper fieldSetMapper;

private FlatFileItemReader<Patient> itemReader;

@Override
public Patient read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
return itemReader.read();
}

public PatientItemReader(@Value("#{jobParameters[filePath]}") String filePath) {
itemReader = new FlatFileItemReader<Patient>();
DefaultLineMapper<Patient> lineMapper = new DefaultLineMapper<Patient>();
DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();
lineTokenizer.setNames(new String[]{"name","surname","idNumber","dob", "email", "cell"});
lineMapper.setLineTokenizer(lineTokenizer);
lineMapper.setFieldSetMapper(fieldSetMapper);
itemReader.setLineMapper(lineMapper);
itemReader.setResource(new FileSystemResource(filePath));
}
}

最佳答案

我想问题是您在 Spring 之外创建读取器并在执行此操作时将其传递给 null 值:

@Bean
public Step step(){
...
.reader(reader(null))
...
}

为了使用像后期绑定(bind)这样的 Spring 功能,你应该做这样的事情:

@Autowired
private ItemReader<Patient> reader;

@Bean
public Step step(){
...
.reader(reader)
...
}

就像你为你的作家所做的那样。

关于java - Spring Boot + Spring Batch + @StepScope = 没有代理 Bean?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34744355/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com