web-dev-qa-db-fra.com

Passer des informations entre les étapes au printemps?

J'essaie de faire un lot printanier et je n'ai aucune expérience avec cela.

Est-il possible de transmettre des informations de chaque étape du lot ou doivent-elles être complètement indépendantes?

Par exemple si j'ai

   <batch:step id="getSQLs" next="runSQLs">
        <batch:tasklet transaction-manager="TransactionManager"
            ref="runGetSQLs" />
    </batch:step>

    <batch:step id="runSQLs">
        <batch:tasklet transaction-manager="TransactionManager"
            ref="runRunSQLs" />
    </batch:step>

Et getSQLs déclenche un bean qui exécute une classe qui génère une liste de type String. Est-il possible de référencer cette liste pour le bean déclenché par runSQL? ("déclenché" n'est peut-être pas le bon terme mais je pense que vous savez ce que je veux dire)

UPDATE: Donc, l'étape getSQLs déclenche ce bean:

<bean id="runGetSQLs" class="myTask"
    scope="step">
    <property name="filePath" value="C:\Users\username\Desktop\sample.txt" />
</bean>

ce qui déclenche la classe myTask qui exécute cette méthode:

  @Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {

    ExecutionContext stepContext = this.stepExecution.getExecutionContext();
    stepContext.put("theListKey", sourceQueries);

    return RepeatStatus.FINISHED;
}

Dois-je en quelque sorte passer stepExecution à la méthode execute?

6
user2665166

Spring Batch prend en charge le transfert de données vers des étapes de travail ultérieures. Cette opération peut être effectuée via la variable ExecutionContext, plus précisément la variable JobExecutionContext. Je fais ici référence à exemple tiré de la documentation officielle , car c’est la référence ultime pour moi:

Pour rendre les données disponibles pour les étapes futures, il devra être "promu" au Job ExecutionContext une fois l’étape terminée. Spring Batch fournit le programme ExecutionContextPromotionListener à cette fin.

L'écouteur doit être configuré avec votre étape, celle qui partage des données avec les futures:

<batch:step id="getSQLs" next="runSQLs">
    <batch:tasklet transaction-manager="TransactionManager"
        ref="runGetSQLs" />
    <listeners>
        <listener>
            <beans:bean id="promotionListener" class="org.springframework.batch.core.listener.ExecutionContextPromotionListener">
                <beans:property name="keys" value="theListKey"/>
            </beans:bean>
        </listener>
    </listeners>
</batch:step>

<batch:step id="runSQLs">
    <batch:tasklet transaction-manager="TransactionManager"
        ref="runRunSQLs" />
</batch:step>

Les données doivent être renseignées à partir de votre bloc de code d'exécution comme suit:

// ...
ExecutionContext stepContext = this.stepExecution.getExecutionContext();
stepContext.put("theListKey", yourList);

Ensuite, dans les étapes suivantes, cette List peut être récupérée avec un crochet de post-calcul annoté avec @BeforeStep a comme suit:

@BeforeStep
public void retrieveSharedData(StepExecution stepExecution) {
    JobExecution jobExecution = stepExecution.getJobExecution();
    ExecutionContext jobContext = jobExecution.getExecutionContext();
    this.myList = jobContext.get("theListKey");
}
8
tmarwen

Méthode de configuration Java.

Étape 1: Configurez ExecutionContextPromotionListener

@Bean
    public ExecutionContextPromotionListener executionContextPromotionListener()
    {
        ExecutionContextPromotionListener executionContextPromotionListener = new ExecutionContextPromotionListener();
        executionContextPromotionListener.setKeys(new String[] {"MY_KEY"});
        return executionContextPromotionListener;   

    }

Étape 2: Configurez l'étape avec ExecutionContextPromotionListener
@Haricot

    public Step myStep() {
        return stepBuilderFactory.get("myStep")
                .<POJO, POJO> chunk(1000)
                .reader(reader()                
                .processor(Processor())
                .writer(Writer()
                .listener(promotionListener())
                .build();
    }

Étape 3: Accéder aux données dans le processeur

    @BeforeStep
    public void beforeStep(StepExecution stepExecution) {
         jobExecutionContext = stepExecution.getJobExecution().getExecutionContext();
         jobExecutionContext.getString("MY_KEY")
    }

Étape 4: définition des données dans le processeur

@BeforeStep
        public void beforeStep(StepExecution stepExecution) {
            stepExecution.getJobExecution().getExecutionContext().put("MY_KEY", My_value);
        }
2
Niraj Sonawane

Je recommande de réfléchir à deux fois au cas où vous souhaiteriez utiliser ExecutionContext pour transmettre des informations entre les étapes. Cela signifie généralement que le travail n'est pas conçu de manière parfaite. L'idée principale de Spring Batch est de traiter d'énormes quantités de données. ExecutionContext utilisé pour stocker des informations sur la progression d'un travail/d'une étape afin de réduire le travail inutile en cas d'échec. C'est par conception que vous ne pouvez pas placer de données volumineuses dans ExectionContext Une fois l’étape terminée, vos informations doivent être lisibles de manière fiable (fichier, base de données, etc.). Ces données peuvent être utilisées lors des étapes suivantes. Pour les travaux simples, je vous recommande d'utiliser uniquement les paramètres de travail comme source d'informations.

Dans votre cas, "runGetSQLs" ne semble pas être un bon candidat pour une étape, mais si vous le souhaitez, vous pouvez l'implémenter en tant que bean Spring et passer automatiquement à l'étape "runRunSQLs" (ce qui est de nouveau un bon candidat pour une étape). En fonction de votre dénomination, runGetSQLs ressemble à ItemReader et runRunSQLs ressemble à ItemWriter. Ils font donc partie d'une étape et non pas d'une étape à l'autre. Dans ce cas, vous n'avez pas besoin de transférer des informations à d'autres étapes.

1
Pavel