最近,我尝试将带有@Value注释的预定义值添加到Bean:
@Component
public class TaskletConfig {
@Bean(name = "FilenameExecutionTasklet")
@JobScope
public Tasklet FilenameExecutionTasklet() {
return new Tasklet() {
@Value("#{jobParameters['inputFilename']}")
private String inputFilename;
@Value("${platformImport.jobParameter.inputFile}")
private String inputFile;
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext().put(inputFile , inputFilename);
return RepeatStatus.FINISHED;
}
};
}
}
以NullPointerException结束。如果我(在一个Tasklet中)(几乎)相同,它可以工作:
@JobScope
@Component
public class FilenameExecutionTasklet implements Tasklet {
@Value("${platformImport.jobParameter.inputFile}")
private String inputFile;
@Value("#{jobParameters['inputFilename']}")
private String inputFilename;
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext().put(inputFile, inputFilename);
return RepeatStatus.FINISHED;
}
}
有人可以告诉我为什么吗?我希望两者都有效。
@Value("${platformImport.jobParameter.inputFile}")
的值在application.yml。
NPE被chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext().put(inputFile , inputFilename);
inputFile
投入。
答案 0 :(得分:1)
我相信你正在击中NPE因为Spring Batch中的后期绑定和评估顺序。因为FilenameExecutionTasklet
能够在JobScope
中,所以它允许Spring Batch在评估@Value
注释之前评估应用程序上下文中的其他bean(单例范围内的那些bean)。
我对此并不乐观,但您可以将@JobScope
添加到TaskletConfig
,或者将@Value
注释移到您的bean创建方法的争论中
@Component
public class TaskletConfig {
@Bean(name = "FilenameExecutionTasklet")
@JobScope
public Tasklet FilenameExecutionTasklet(
@Value("#{jobParameters['inputFilename']}") String inputFilename,
@Value("${platformImport.jobParameter.inputFile} String inputFile ) {
return new Tasklet() {
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext().put(inputFile , inputFilename);
return RepeatStatus.FINISHED;
}
};
}
}
除此之外,我还不太确定你的用例是什么。如果文件名是作为作业参数提供的,那么将它放在执行上下文中是什么意思?
事实上,Tasklet已经可以通过ChunkContext
:
public RepeatStatus execute(final StepContribution Contribution, final ChunkContext chunkContext) throws Exception {
String fileName;
//one way
fileName = chunkContext.getStepContext().getStepExecution().getJobExecution().getJobParameters().getString("inputFileName");
//another way
fileName = (String) chunkContext.getStepContext().getJobParameters().get("inputFileName");
return null;
}