Stocker dans JobExecutionContext à partir de tasklet et accéder dans un autre tasklet
j'ai une condition dans laquelle une tasklet, stocke tous les fichiers dans les répertoires dans une arraylist. La taille de la liste est stockée dans le contexte d'exécution des tâches. Plus tard, ce compte est accédé à partir d'un autre tasklet dans une autre étape. Comment faire cela. J'ai essayé de stocker dans le contexte jobexécution, à runtime jette collection unmodifiable exception,
public RepeatStatus execute(StepContribution arg0, ChunkContext arg1)
throws Exception {
StepContext stepContext = arg1.getStepContext();
StepExecution stepExecution = stepContext.getStepExecution();
JobExecution jobExecution = stepExecution.getJobExecution();
ExecutionContext jobContext = jobExecution.getExecutionContext();
jobContext.put("FILE_COUNT",150000);
a également stocké la référence stepexection dans l'annotation beforestep .toujours pas possioble.veuillez me faire savoir ,comment les partager des données entre deux tasklets.
2 réponses
vous avez au moins 4 possibilités:
- utilisez L'Exécutionpromotionlistener pour passer des données aux étapes à venir
- utiliser une fève (ressort) pour conserver les données inter-étapes, p.ex. une carte à balise concurrente
- sans autre action de ces données ne sera pas accessible pour un re-démarrage
- accédez au JobExecutionContext dans votre tasklet, doit être utilisé avec prudence, va causer des problèmes de thread pour les étapes parallèles
- utilisation la nouvelle jobscope (introduite avec spring batch 3)
définir une valeur
public class ChangingJobExecutionContextTasklet implements Tasklet { /** {@inheritDoc} */ @Override public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { // set variable in JobExecutionContext chunkContext .getStepContext() .getStepExecution() .getJobExecution() .getExecutionContext() .put("value", "foo"); // exit the step return RepeatStatus.FINISHED; } }
extraction d'une valeur
public class ReadingJobExecutionContextTasklet implements Tasklet { private static final Logger LOG = LoggerFactory.getLogger(ChangingJobExecutionContextTasklet.class); /** {@inheritDoc} */ @Override public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { // pull variable from JobExecutionContext String value = (String) chunkContext .getStepContext() .getStepExecution() .getJobExecution() .getExecutionContext() .get("value"); LOG.debug("Found value in JobExecutionContext:" + value); // exit the step return RepeatStatus.FINISHED; } }
j'ai créé des exemples de code pour les 3 premières solutions mon ressort-lot-exemples github, voir module complexe et d'emballage interstepcommunication
une Autre façon est d'utiliser StepExecutionListener
qui est appelé après l'exécution step.
Votre tasklet peut l'implémenter et partager un attribut local.
public class ReadingJobExecutionContextTasklet implements Tasklet, StepExecutionListener {
private String value;
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
ExecutionContext jobExecutionContext = stepExecution.getJobExecution().getExecutionContext();
jobExecutionContext.put("key", value);
//Return null to leave the old value unchanged.
return null;
}
}
ainsi, dans l'étape, votre haricot est un tasklet et un auditeur comme bellow. Vous devez également configurer la portée de votre pas en "step":
<batch:step id="myStep" next="importFileStep">
<batch:tasklet>
<ref bean="myTasklet"/>
<batch:listeners>
<batch:listener ref="myTasklet"/>
</batch:listeners>
</batch:tasklet>
</batch:step>
<bean id="myTasklet" class="ReadingJobExecutionContextTasklet" scope="step">