【发布时间】:2021-10-28 08:44:49
【问题描述】:
我正在处理使用 Spring Batch 编写的批处理,并且我有一个读取器/写入器组件,可以轻松地将其用于同一进程的多个实例化。 reader 和 writer 都是通用的,并且依赖于接口来实现其功能,但由于某些奇怪的原因,无法自动装配通用类型。这是我的设置。
我有一个接口,这样描述要执行的步骤,我有这个接口的 11 个实现:
import java.util.List;
public interface Process<E> {
List<E> determineChanges(List<Integer> approvalIds);
void applyChanges(List<E> changeCto);
}
接下来我定义了读写器实现如下:
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.NonTransientResourceException;
import org.springframework.batch.item.ParseException;
import org.springframework.batch.item.UnexpectedInputException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@StepScope
public class GenericApprovalReader<T extends Process<U>, U> implements ItemReader<List<U>> {
private final SomeOtherBeanStepScopedBean otherBean;
private final T processor;
@Autowired
public GenericApprovalReader(SomeOtherBeanStepScopedBean otherBean,
T processor) {
this.SomeOtherBean = otherBean;
this.processor= processor;
}
@Override
public List<U> read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
List<Integer> items = this.someOtherBean.read();
if(items != null) {
return processor.determineChanges(items );
} else {
return null;
}
}
}
同样,我有一个作家:
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@StepScope
// Note that second type parameter is necessary only due to necessity to parametrize the ItermWriter<List<U>> with the
// same type as is used for parametrization of Approval<U>
public class GenericApprovalWriter<T extends Process<U>, U> implements ItemWriter<List<U>> {
private final T processor;
@Autowired
public GenericApprovalWriter(T processor) {
this.approvalProcessor = processor;
}
@Override
public void write(List<? extends List<U>> items) throws Exception {
for(List<U> item: items) {
this.processor.applyChanges(item);
}
}
}
现在,当我尝试在某些 @Configuration 类中连接我的 Step 中的读者和作者时,如下所示:
@Bean(name="firstProcessingStep")
Step firstProcessingStep(GenericApprovalReader<FirstProcessor, Item> reader,
GenericApprovalWriter<FirstProcessor, Item> writer) {
return stepBuilderFactory.get("firstProcessingStep")
.<List<Item>,List<Item>>chunk(CHUNK_SIZE)
.reader(reader)
.writer(writer)
.allowStartIfComplete(false)
.build();
}
我得到以下异常:
org.springframework.beans.factory.NoUniqueBeanDefinitionException: 没有“?”类型的合格 bean可用:预期的单个匹配 bean,但找到 11
为什么会出现此错误?尽管指定了具体类型,为什么 Spring 无法构造正确的编写器和读取器的通用实例?
根据this other post about Autowiring of generic beans in Spring,这种行为应该在我正在使用的 Spring 4.0 之后才有可能。
【问题讨论】:
-
如果你将 @Autowire GenericApprovalReader
阅读器作为属性而不是方法参数 -
同样的错误也失败了。
标签: java spring spring-boot generics autowired