Spring无法连接通用Bean -没有类型的合格Bean

bakd9h0s  于 2022-11-21  发布在  Spring
关注(0)|答案(1)|浏览(190)

我正在使用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之后,这种行为应该是可能的。

yeotifhr

yeotifhr1#

当自动连接的Bean与Spring Boot 应用程序上下文中的两个或多个已加载Bean相匹配时,将出现预期的单个匹配Bean,但却找到。当在 Spring 引导中自动连接的Bean与上下文中的两个或多个Bean相匹配时,将在上下文中找到两个或多个Bean。因此,无法自动连接该Bean。请考虑将其中一个Bean标记为**@Primary**,更新使用者以接受多个Bean,或使用**@限定符来标识应使用的Bean。预期有一个匹配的Bean,但找到了n个。
该类应使用
@Primary进行注解。注解的@Primary类被视为自动连接中的默认类。@Autowired注解加载@Primary**Bean并向其添加接口或抽象变量。
像这样更改代码。

@Component
@Primary    
@StepScope
public class GenericApprovalReader<T extends Process<U>, U> implements ItemReader<List<U>> {
//content

@Component
@Primary    
@StepScope
 GenericApprovalWriter<T extends Process<U>, U> implements ItemWriter<List<U>> {

//content

相关问题