Issue retrieving a ExecutionContext from a SkipListener

一笑奈何 提交于 2021-02-05 07:09:29

问题


I am trying to retrieve a spring batch ExecutionContext from a SkipListener.

Here is what I have attempted (I rely on annotations instead of interfaces in order to implement my listeners):

import com.xxxx.domain.UserAccount;
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.annotation.BeforeStep;
import org.springframework.batch.core.annotation.OnSkipInWrite;
import org.springframework.mail.MailSendException;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class MailSkipListener {

    private StepExecution stepExecution;

    @BeforeStep
    public void saveStepExecution(StepExecution stepExecution) {
        this.stepExecution = stepExecution;
    }

    @OnSkipInWrite
    public void logSkippedEmail(UserAccount userAccount, Throwable t) {
        if (t instanceof MailSendException) {
            MailSendException e = (MailSendException) t;
            log.warn("FailedMessages: " + e.getFailedMessages());
        }
    }
}

However, the logSkippedEmail method is never executed when a MailSendException is raised. When I remove the saveStepExecution method, the logSkippedEmail is again executed in case of a MailSendException.

I register my MailSkipListener as follows:

@Bean
public Step messagesDigestMailingStep(EntityManagerFactory entityManagerFactory) {
    return stepBuilderFactory
            .get("messagesDigestMailingStep")
            .<UserAccount, UserAccount>chunk(5)

            ...

            .writer(itemWriter)
            .listener(mailSkipListener)//Here
            .build();
}

What I am trying to achieve here is retrieving an ExecutionContext from my SkipListener. How can this be achieved? It seems there's no way to autowire theExecutionContext.


回答1:


This is quite an old question, but I just struggled with this too. I ended up registering the skiplistener twice in order for it to work, once as a StepExecutionListener and another as a SkipListener. It sucks, but it seems to work:

@Bean
public Step messagesDigestMailingStep(EntityManagerFactory entityManagerFactory) {
    return stepBuilderFactory
        .get("messagesDigestMailingStep")
        .<UserAccount, UserAccount>chunk(5)

        ...

        .writer(itemWriter)
        .listener((StepExecutionListener) mailSkipListener) // <--- 1
        .listener((SkipListener) mailSkipListener)          // <--- 2
        .build();
}



回答2:


You can implement StepExecutionListener on your MailSkipListener to save the context in your stepExecution during the beforeStep() method :

public class MailSkipListener implements StepExecutionListener {

    @Override
    public void beforeStep(StepExecution stepExecution) {
         this.stepExecution = stepExecution;
    }


来源:https://stackoverflow.com/questions/43987089/issue-retrieving-a-executioncontext-from-a-skiplistener

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!