从Spring Batch ItemProcessor返回多个项目 [英] Return multiple items from spring batch ItemProcessor

查看:105
本文介绍了从Spring Batch ItemProcessor返回多个项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个春季批处理作业,在其中一个步骤中,我为处理器提供了以下代码:

I'm writing a spring batch job and in one of my step I have the following code for the processor:

@Component
public class SubscriberProcessor implements ItemProcessor<NewsletterSubscriber, Account>, InitializingBean {

    @Autowired
    private AccountService service;

    @Override public Account process(NewsletterSubscriber item) throws Exception {
        if (!Strings.isNullOrEmpty(item.getId())) {
            return service.getAccount(item.getId());
        }
        // search with email address
        List<Account> accounts = service.findByEmail(item.getEmail());
        checkState(accounts.size() <= 1, "Found more than one account with email %s", item.getEmail());
        return accounts.isEmpty() ? null : accounts.get(0);
    }

    @Override public void afterPropertiesSet() throws Exception {
        Assert.notNull(service, "account service must be set");
    }
}

上面的代码有效,但是我发现在某些极端情况下,每个 NewsletterSubscriber 允许有多个 Account .因此,我需要删除状态检查,并将多个 Account 传递给项目编写者.

The above code works but I've found out that there are some edge cases where having more than one Account per NewsletterSubscriber is allowed. So I need to remove the state check and to pass more than one Account to the item writer.

我发现的一个解决方案是同时更改 ItemProcessor ItemWriter 以处理 List< Account> 类型而不是 Account ,但这有两个缺点:

One solution I found is to change both ItemProcessor and ItemWriter to deal with List<Account> type instead of Account but this have two drawbacks:

  • 由于编写器中存在嵌套列表,因此代码和测试更加丑陋,难以编写和维护.
  • 最重要的一个以上 Account 对象可能会写在同一笔交易中,因为发给writer的列表可能包含多个帐户,我想避免这种情况.
  • Code and tests are uglier and harder to write and maintain because of nested lists in writer
  • Most important more than one Account object may be written in the same transaction because a list given to writer may contain multiple accounts and I'd like to avoid this.

有什么方法可以使用侦听器,或者替换spring批处理使用的一些内部组件来避免处理器中的列表?

Is there any way, maybe using a listener, or replacing some internal component used by spring batch to avoid lists in processor?

我已经针对此问题打开了 Spring Jira上的一个问题.

I've opened an issue on spring Jira for this problem.

我正在调查/core/step/item/SimpleChunkProcessor.java#L233"rel =" noreferrer> SimpleChunkProcessor 看看我是否可以通过某种方式使用它们来实现自己的目标.

I'm looking into isComplete and getAdjustedOutputs methods in FaultTolerantChunkProcessor which are marked as extension points in SimpleChunkProcessor to see if I can use them in some way to achieve my goal.

欢迎任何提示.

推荐答案

项目处理器将一件东西带进去,并返回一个列表

MyItemProcessor implements ItemProcessor<SingleThing,List<ExtractedThingFromSingleThing>> {
    public List<ExtractedThingFromSingleThing> process(SingleThing thing) {
    //parse and convert to list
    }
}

包装下游编写器以解决问题.这样,作者下游的内容就不必使用列表了.

@StepScope
public class ItemListWriter<T> implements ItemWriter<List<T>> {
    private ItemWriter<T> wrapped;

    public ItemListWriter(ItemWriter<T> wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public void write(List<? extends List<T>> items) throws Exception {
        for (List<T> subList : items) {
            wrapped.write(subList);
        }
    }
}

这篇关于从Spring Batch ItemProcessor返回多个项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆