Spring batch 从SkipListener检索ExecutionContext时出现问题

Spring batch 从SkipListener检索ExecutionContext时出现问题,spring-batch,Spring Batch,我正在尝试从SkipListener检索spring批处理ExecutionContext 以下是我的尝试(我依靠注释而不是接口来实现我的侦听器): 导入com.xxxx.domain.UserAccount; 导入lombok.extern.slf4j.slf4j; 导入org.springframework.batch.core.StepExecution; 导入org.springframework.batch.core.annotation.BeforeStep; 导入org.sprin

我正在尝试从
SkipListener
检索spring批处理
ExecutionContext

以下是我的尝试(我依靠注释而不是接口来实现我的侦听器):

导入com.xxxx.domain.UserAccount;
导入lombok.extern.slf4j.slf4j;
导入org.springframework.batch.core.StepExecution;
导入org.springframework.batch.core.annotation.BeforeStep;
导入org.springframework.batch.core.annotation.OnSkipInWrite;
导入org.springframework.mail.MailSendException;
导入org.springframework.stereotype.Component;
@Slf4j
@组成部分
公共类MailSkipListener{
私人分步执行分步执行;
@先于
公共无效保存步骤执行(步骤执行步骤执行){
this.stepExecution=stepExecution;
}
@OnSkipInWrite
public void logSkippedEmail(UserAccount UserAccount,Throwable t){
if(MailSendException的t实例){
MailSendException e=(MailSendException)t;
log.warn(“FailedMessages:+e.getFailedMessages());
}
}
}
但是,当引发
MailSendException
时,不会执行
logSkippedEmail
方法。当我删除
savestepeexecution
方法时,如果出现
MailSendException
,将再次执行
logSkippedEmail

我注册我的
MailSkipListener
如下:

@Bean
公共步骤消息DigestmailingStep(EntityManagerFactory EntityManagerFactory){
返回stepBuilderFactory
.get(“messagesDigestMailingStep”)
.chunk(5)
...
.writer(项目编写器)
.listener(mailSkipListener)//此处
.build();
}
我在这里试图实现的是从我的
SkipListener
检索
ExecutionContext
。如何做到这一点?似乎没有办法自动连接
ExecutionContext

您可以在
MailSkipListener
上实现,以便在
beforeStep()
方法期间将上下文保存在
stepExecution
中:

公共类MailSkipListener实现StepExecutionListener{
@凌驾
预处理前的公共无效(步骤执行步骤执行){
this.stepExecution=stepExecution;
}

这是一个很老的问题,但我也在努力解决这个问题。 为了让它工作,我注册了两次skiplistener,一次是StepExecutionListener,另一次是skiplistener。 这很糟糕,但似乎有效:

@Bean
公共步骤消息DigestmailingStep(EntityManagerFactory EntityManagerFactory){
返回stepBuilderFactory
.get(“messagesDigestMailingStep”)
.chunk(5)
...
.writer(项目编写器)

.listener((StepExecutionListener)mailSkipListener)/我知道这是一个老问题,但我必须自己解决这个问题,并完成了以下实现,其中我让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);
    }
}
@组件
公共类PersonImportListener实现SkipListener、StepExecutionListener{
私有最终记录器Logger=LoggerFactory.getLogger(this.getClass());
私人分步执行分步执行;
@凌驾
预处理前的公共无效(步骤执行步骤执行){
this.stepExecution=stepExecution;
}
@凌驾
公共出口状态后步骤(步骤执行步骤执行){
返回ExitStatus.COMPLETED;
}
@凌驾
公共无效OnSkipRead(可丢弃可丢弃){
logger.warn(“读取时跳过行”,可丢弃);
}
@凌驾
公共无效onSkipInWrite(个人,可丢弃){
warn(“写入时跳过Bean”,可丢弃);
logger.warn(“执行上下文”+步骤执行);
}
@凌驾
在Skipin过程中公开作废(个人,可丢弃){
warn(“进程中跳过了Bean”,可丢弃);
}
}
并将该类用作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();
}
@Bean
公共步骤步骤1(JdbcBatchItemWriter编写器){
PersonImportListener=新PersonImportListener();
返回stepBuilderFactory.get(“step1”)
.chunk(10)
.reader(reader())
.容错()
斯基普利米特先生(10)
.skip(DataIntegrityViolationException.class)
.listener((StepExecutionListener)侦听器)
.listener((SkipListener)listener)
.processor(处理器())
.作者(作者)
.build();
}

Hi Thrax。这是我在上面尝试过的,但使用注释而不是界面