我正在使用Spring Batch编写一个批处理,我有一个读取器/写入器组件,可以很容易地重用同一进程的多个示例。读取器和写入器都是泛型的,它们的功能依赖于一个接口,但是泛型类型由于一些奇怪的原因不能自动连接。下面是我的设置。
我有一个接口,它描述了要像这样执行的步骤,我有这个接口的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();
}
我得到以下异常:
异常错误:没有类型为'?'的合格Bean可用:应为单个匹配Bean,但找到11个
为什么我会得到这个错误?为什么Spring不能构造正确的writer和reader的泛型示例,尽管指定了具体的类型?
根据this other post about Autowiring of generic beans in Spring,在我正在使用的Spring 4.0之后,这种行为应该是可能的。
1条答案
按热度按时间yeotifhr1#
当自动连接的Bean与Spring Boot 应用程序上下文中的两个或多个已加载Bean相匹配时,将出现预期的单个匹配Bean,但却找到。当在 Spring 引导中自动连接的Bean与上下文中的两个或多个Bean相匹配时,将在上下文中找到两个或多个Bean。因此,无法自动连接该Bean。请考虑将其中一个Bean标记为**@Primary**,更新使用者以接受多个Bean,或使用**@限定符来标识应使用的Bean。预期有一个匹配的Bean,但找到了n个。
该类应使用@Primary进行注解。注解的@Primary类被视为自动连接中的默认类。@Autowired注解加载@Primary**Bean并向其添加接口或抽象变量。
像这样更改代码。
或