Solución:
tienes al menos 4 posibilidades:
- use ExecutionPromotionListener para pasar datos a pasos futuros
- use un bean (spring) para contener datos entre pasos, por ejemplo, un ConcurrentHashMap
- sin más acciones, no se podrá acceder a estos datos para reiniciar
- acceder al JobExecutionContext en su tasklet, debe usarse con precaución, causará problemas de subprocesos para pasos paralelos
- utilizar el nuevo visor de trabajo (introducido con el lote de primavera 3)
Ejemplo de código para acceder a JobExecution desde Tasklet:
-
establecer un valor
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; } }
-
extrayendo un valor
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; } }
Creé ejemplos de código para las primeras 3 soluciones en mi repositorio de github spring-batch-examples, ver módulo complejo y paquete comunicacion interespaso
Otra forma es usar StepExecutionListener
que se llama después de la ejecución del paso. Su tasklet puede implementarlo y compartir el atributo 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;
}
}
Entonces, en el paso, su bean es un tasklet y un oyente como bellow. También debe configurar el alcance de su paso a “paso”:
<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">
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)