java - @Value注解区分类和bean

标签 java spring spring-batch spring-annotations

最近,我尝试将带有@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(单例范围内的那些)注释。

我对此并不肯定,但您可以添加 @JobScopeTaskletConfig或者改为移动 @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/

相关文章:

java - 使用 spring-java-config 创建一个 'decider-step-loop'

java - Spring Batch 中多个数据源的使用

java - AS400 作业线程详细信息

java - 玩 Java Akka - Await.result 期待可等待对象但不接受 Future<Object>

spring - 如何在 r2dbc 中批量执行多个插入?

java - SpringBoot 未加载使用 OpenAPI 3.0 生成的 Controller

java - 如何向外部 Rest Api 发出 Http Post 请求?

基于 Spring Batch block 的方法在 Item Writer 中调用 REST API

java - 在这种情况下,Observable 会不会因为被垃圾收集而中途停止发射?

java - 如何在 EclipseLink 中配置查询缓存