2016-06-30 15 views
2

Vor kurzem habe ich versucht, einen vordefinierten Wert mit der @Value Anmerkung zu einem Bean hinzuzufügen:Unterschied zwischen Klasse und Bohnen durch @Value Anmerkung

@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; 
     } 

    }; 
    } 
} 

, die in einem Nullpointer endet. Wenn ich (fast) das gleiche tun in einem Tasklet, funktioniert es:

@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; 
    } 
} 

Könnte jemand bitte sagen, meine warum? Ich hätte erwartet, dass beide arbeiten. Der Wert @Value("${platformImport.jobParameter.inputFile}") ist in der application.yml.

NPE wird in chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext().put(inputFile , inputFilename); mit inputFile geworfen.

+0

Auf welcher Linie Sie haben NPE im ersten Beispiel? –

+0

Sorry, vergessen zu sagen: Siehe bearbeiten. –

Antwort

1

Ich glaube, dass Sie die NPE treffen, weil späte Bindung und Reihenfolge der Auswertung innerhalb Spring Batch. Da FilenameExecutionTasklet competent in JobScope ist, ermöglicht es Spring Batch, andere Beans (die im Singleton-Bereich) im Anwendungskontext VOR der Auswertung der @Value Annotation zu bewerten.

Ich bin nicht positiv, aber Sie können möglicherweise @JobScope zu TaskletConfig hinzufügen oder stattdessen verschieben Sie die @Value Annotationen als Argumente zu Ihrer Bean-Erstellungsmethode.

@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; 
     } 

    }; 
    } 

} 

Abgesehen davon bin ich mir nicht ganz sicher, was Ihr Anwendungsfall hier ist. Wenn der Dateiname als Job-Parameter angegeben wird, warum sollte er dann in den Ausführungskontext eingefügt werden?

In der Tat das Tasklet bereits Zugriff haben über die 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; 
} 
+0

Hey! Danke für deine Antwort. Ihr erster Absatz klingt vernünftig. Ich bin nicht so tief in den Frühling Stapel, um zu wissen, was unter der Oberfläche all dieser Anmerkungen ist. Leider war dein Vorschlag, die @JobScope Annotation auf die 'TaskletConfig'-Ebene zu setzen, nicht richtig. Aber ich wusste nicht, dass ich auf die JobParameters in ähnlicher Weise wie den 'ExecutionContext' zugreifen kann. Dank dafür. (Grund für die Verbesserung.) –

+0

Interessant, dass die @JobScope-Platzierung keinen Effekt hat. Haben Sie aus Neugierde auch versucht, die '@ Value'-Eigenschaften als Argumente für die' FilenameExecutionTasklet() '-Methode zu verwenden? –

Verwandte Themen