问题
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