繁体   English   中英

如何使用复合项目处理器在 spring 批处理中使用 @BeforeStep 获取 jobId?

[英]How to get jobId with @BeforeStep in spring batch with compositeItem processor?

我有一个像这样的复合项目处理器:

@Bean
    public CompositeItemProcessor<User, User> compositeItemProcessor() throws Exception {
        CompositeItemProcessor<User, User> processor = new CompositeItemProcessor<>();
        List<ItemProcessor<User, User>> processors = Arrays.asList(new Processor(),validatingItemProcessor());
        processor.setDelegates(processors);
        processor.afterPropertiesSet();
        return processor;
    }

我无法使用jobExecutionId在任何进程中@Beforestep这是处理器 1。


public class Processor implements ItemProcessor<User, User>  {

    private static final Map<String, String> DEPT_NAMES =
            new HashMap<>();

    private Long jobExecutionId;

    @BeforeStep
    public void beforeStep(StepExecution stepExecution) {
        this.jobExecutionId = stepExecution.getJobExecutionId();
    }

    public Processor() {
        DEPT_NAMES.put("001", "Technology");
        DEPT_NAMES.put("002", "Operations");
        DEPT_NAMES.put("003", "Accounts");
    }

    @Override
    public User process(User user) throws Exception {
        System.out.println(this.jobExecutionId);
        String deptCode = user.getDept();
        String dept = DEPT_NAMES.get(deptCode);
        user.setDept(dept);
        user.setTime(new Date());
        System.out.println(String.format("Converted from [%s] to [%s]", deptCode, dept));
        return user;
    }

}

这是处理器 2。


    @Bean
    public ValidatingItemProcessor<User> validatingItemProcessor() {
        return new ValidatingItemProcessor<>(new UserValidator());
    }

这是我的工作配置。

       Step step = stepBuilderFactory.get("ETL-file-load")
                .<User, User>chunk(100)
                .reader(itemReader)
                .processor(compositeItemProcessor())
                .writer(itemWriter)
                .faultTolerant()
                .skipPolicy(jobSkipPolicy())
                .listener(userValidationListener())
                .build();


        return jobBuilderFactory.get("ETL-Load")
                .incrementer(new RunIdIncrementer())
                .start(step)
                .build();

我正在为跳过的用户记录使用侦听器。

    @Bean
    public UserValidationListener userValidationListener() {
        return new UserValidationListener();
    }
public class UserValidationListener implements SkipListener<User, User> {


    @Override
    public void onSkipInRead(Throwable throwable) {

    }

    @Override
    public void onSkipInWrite(User user, Throwable throwable) {

    }

    @Override
    public void onSkipInProcess(User user, Throwable throwable) {
        System.out.println(user.toString());
        System.out.println(throwable.getMessage());
        //write error
        //errorStaorage.()
    }
}

使用此配置,我无法在任何处理器中获取jobExecutionId

我尝试过使用单个处理器而不是复合处理器。 我得到了jobExecutionId

        Step step = stepBuilderFactory.get("ETL-file-load")
                .<User, User>chunk(100)
                .reader(itemReader)
                .processor(new Processor())
                .writer(itemWriter)
                .faultTolerant()
                .skipPolicy(jobSkipPolicy())
                .listener(userValidationListener())
                .build();

我得到了jobExecutionId

Converted from [001] to [Technology]
1
Converted from [002] to [Operations]
1
Converted from [003] to [Accounts]
1
Converted from [001] to [Technology]
1
Converted from [001] to [Technology]

其中1是 jobId。 因此,这使我得出一个结论,即我设置composite processor的方式存在错误,无法使用@BeforeStep获取id

为什么@Beforestep在使用复合项目处理器时表现不同并且不会被调用?

更新根据建议的答案,我添加了这个。

    @Bean
    public Processor itemProcessor() {
        return new Processor();
    }

现在我的步骤看起来像这样......

        Step step = stepBuilderFactory.get("ETL-file-load")
                .<User, User>chunk(100)
                .reader(itemReader)
                .processor(compositeItemProcessor())
                .writer(itemWriter)
                .faultTolerant()
                .skipPolicy(jobSkipPolicy())
                .listener(userValidationListener())
                .listener(itemProcessor())
                .build();

问题是您的处理器没有被隐式注册为侦听器,只有复合处理器是。 您需要在您的步骤中明确执行此操作

    @Bean
    public CompositeItemProcessor<User, User> compositeItemProcessor() throws Exception {
        CompositeItemProcessor<User, User> processor = new CompositeItemProcessor<>();
        List<ItemProcessor<User, User>> processors = Arrays.asList(processor(), validatingItemProcessor());
        processor.setDelegates(processors);
        processor.afterPropertiesSet();
        return processor;
    }

    @Bean
    public ItemProcessor<User, User> processor() {
        return new Processor();
    }

    @Bean
    public void step() {
        Step step = stepBuilderFactory.get("ETL-file-load")
                .<User, User>chunk(100)
                .reader(itemReader)
                .processor(compositeItemProcessor())
                .writer(itemWriter)
                .faultTolerant()
                .skipPolicy(jobSkipPolicy())
                .listener(userValidationListener())
                .listener(processor()) // register your custom processor as a listener to execute @BeforeStep
                .build();
        return step;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM