我正在尝试从ExecutionContext
检索弹出批处理SkipListener
。
这是我尝试过的(我依靠注释而不是接口来实现我的听众):
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());
}
}
}
但是,引发logSkippedEmail
时,永远不会执行MailSendException
方法。当我删除saveStepExecution
方法时,logSkippedEmail
会再次执行MailSendException
。
我注册我的MailSkipListener
如下:
@Bean
public Step messagesDigestMailingStep(EntityManagerFactory entityManagerFactory) {
return stepBuilderFactory
.get("messagesDigestMailingStep")
.<UserAccount, UserAccount>chunk(5)
...
.writer(itemWriter)
.listener(mailSkipListener)//Here
.build();
}
我在这里尝试实现的是从ExecutionContext
中检索SkipListener
。怎么能实现这一目标?似乎没有办法自动装配ExecutionContext
。
答案 0 :(得分:0)
您可以在MailSkipListener
上实施StepExecutionListener
,以便在stepExecution
方法中保存beforeStep()
内容:
public class MailSkipListener implements StepExecutionListener {
@Override
public void beforeStep(StepExecution stepExecution) {
this.stepExecution = stepExecution;
}
答案 1 :(得分:0)
这是一个很老的问题,但我也只是在努力解决这个问题。 我最后两次注册skiplistener以使其工作,一次作为StepExecutionListener而另一次作为SkipListener。 它很糟糕,但似乎有效:
{{1}}
答案 2 :(得分:0)
我知道这是一个老问题,但我不得不自己处理这个问题,并整理了以下实现,其中我让 SkipListener 也实现了 StepExecutionListener,并添加了与 SkipListener 和 StepExecutionListener 相同的类。
@Component
public class PersonImportListener implements SkipListener<Person, Person>, StepExecutionListener {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private StepExecution stepExecution;
@Override
public void beforeStep(StepExecution stepExecution) {
this.stepExecution = stepExecution;
}
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
return ExitStatus.COMPLETED;
}
@Override
public void onSkipInRead(Throwable throwable) {
logger.warn("Line skipped on read", throwable);
}
@Override
public void onSkipInWrite(Person person, Throwable throwable) {
logger.warn("Bean skipped on write", throwable);
logger.warn("Execution Context" + stepExecution);
}
@Override
public void onSkipInProcess(Person person, Throwable throwable) {
logger.warn("Bean skipped on process", throwable);
}
}
并将此类用作 StepExecutionListener 和 SkipListener 的侦听器。
@Bean
public Step step1(JdbcBatchItemWriter<Person> writer) {
PersonImportListener listener = new PersonImportListener();
return stepBuilderFactory.get("step1")
.<Person, Person> chunk(10)
.reader(reader())
.faultTolerant()
.skipLimit(10)
.skip(DataIntegrityViolationException.class)
.listener((StepExecutionListener) listener)
.listener((SkipListener) listener)
.processor(processor())
.writer(writer)
.build();
}