我正在编写一个Spring Batch作业,在其中一个步骤中,我的处理器代码如下:
@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
对象,我想避免这种情况。
是否有任何方法,例如使用监听器或替换Spring Batch使用的某些内部组件,以避免在处理器中使用列表?
更新
我已经在Spring Jira上提交了一个问题来解决这个问题。
我正在研究FaultTolerantChunkProcessor
中标记为 SimpleChunkProcessor
的扩展点的 isComplete 和 getAdjustedOutputs 方法,以查看是否能够在某种程度上使用它们来实现我的目标。
欢迎任何提示。