![](/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.