![](/img/trans.png)
[英]Spring Batch- how to pass list of multiple items from input to ItemReader, ItemProcessor and ItemWriter
[英]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
傳遞給項目編寫者。
我找到的一個解決方案是更改ItemProcessor
和ItemWriter
以處理List<Account>
類型而不是Account
但這有兩個缺點:
Account
對象可以寫在同一個事務中,因為給寫入者的列表可能包含多個帳戶,我想避免這種情況。 有沒有辦法,可能使用一個監聽器,或者更換一些彈簧批處理使用的內部組件以避免處理器中的列表?
我期待到isComplete和getAdjustedOutputs的方法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
而沒有深入雜草。 如果您真的想知道ItemProcessor
和ItemWriter
之間的關系退出( 不推薦 ),請查看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.