Saltar al contenido

Almacenar en JobExecutionContext desde tasklet y acceder a otro tasklet

Solución:

tienes al menos 4 posibilidades:

  1. use ExecutionPromotionListener para pasar datos a pasos futuros
  2. 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
  3. acceder al JobExecutionContext en su tasklet, debe usarse con precaución, causará problemas de subprocesos para pasos paralelos
  4. utilizar el nuevo visor de trabajo (introducido con el lote de primavera 3)

Ejemplo de código para acceder a JobExecution desde Tasklet:

  1. 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;
        }
    
    }
    
  2. 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)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *