簡體   English   中英

從spring批處理ItemProcessor返回多個項目

[英]Return multiple items from spring batch ItemProcessor

我正在編寫一個Spring批處理作業,在我的一個步驟中,我有以下處理器代碼:

@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傳遞給項目編寫者。

我找到的一個解決方案是更改ItemProcessorItemWriter以處理List<Account>類型而不是Account但這有兩個缺點:

  • 由於編寫器中的嵌套列表,代碼和測試更加難以編寫和維護
  • 最重要的是,多個Account對象可以寫在同一個事務中,因為給寫入者的列表可能包含多個帳戶,我想避免這種情況。

有沒有辦法,可能使用一個監聽器,或者更換一些彈簧批處理使用的內部組件以避免處理器中的列表?

更新

我已經在春季Jira上為這個問題打開了一個問題。

我期待到isCompletegetAdjustedOutputs的方法FaultTolerantChunkProcessor被標記為擴展點SimpleChunkProcessor ,看看我是否能以某種方式使用它們來實現我的目標。

任何提示都是受歡迎的。

Item Processor接受一件事,並返回一個列表

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而沒有深入雜草。 如果您真的想知道ItemProcessorItemWriter之間的關系退出( 不推薦 ),請查看ChunkProcessor接口的實現。 雖然簡單的情況( SimpleChunkProcessor )並沒有那么糟糕,但如果你使用任何容錯邏輯(通過FaultTolerantChunkProcessor跳過/重試),它會非常快速。

一個更簡單的選擇是將此邏輯移動到ItemReader ,在返回項目之前執行此豐富。 在返回項目之前,在您執行服務查找的自定義ItemReader實現中包裝您正在使用的任何ItemReader 在這種情況下,您不會從閱讀器返回NewsletterSubscriber ,而是根據之前的信息返回一個Account

您返回的不是返回帳戶,而是創建AccountWrapper或Collection。 作家顯然必須考慮到這一點:)

您可以使用變換器將Pojo(Pojo對象從文件)轉換為您的實體通過制作以下代碼:

public class Intializer {

public static LGInfo initializeEntity() throws Exception {
    Constructor<LGInfo> constr1 = LGInfo.class.getConstructor();
    LGInfo info = constr1.newInstance();
    return info;
}
}

並在你的項目處理器

public class LgItemProcessor<LgBulkLine, LGInfo> implements ItemProcessor<LgBulkLine, LGInfo> {

private static final Log log = LogFactory.getLog(LgItemProcessor.class);

@SuppressWarnings("unchecked")
@Override
public LGInfo process(LgBulkLine item) throws Exception {
    log.info(item);
    return (LGInfo) Intializer.initializeEntity();
}

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM