最近,我尝试将带有@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
中抛出。
最佳答案
我相信您遇到了 NPE,因为 Spring Batch 中的延迟绑定(bind)和求值顺序。因为FilenameExecutionTasklet
主管在JobScope
,它允许 Spring Batch 在评估 @Value
之前评估应用程序上下文中的其他 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;
}
关于java - @Value注解区分类和bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38125126/