考虑将其中一个 bean 标记为 @Primary

Jef*_*eff 8 java spring

在我的 Java spring 应用程序中,我有

public class BinarySearchImpl {

    @Autowired
    @Qualifier("Quick")
    SortAlgorithem sorter;

    Log log=LogFactory.getLog(BinarySearchImpl.class);

    public BinarySearchImpl(SortAlgorithem sorter) {
        log.info("Binary Search Bean is created");
        this.sorter=sorter;
    }
Run Code Online (Sandbox Code Playgroud)

SortAlgorithem 是一个接口,它使我的应用程序松散耦合:

public interface SortAlgorithem {

    public int[] sort(int[] arrayNumbers);

}
Run Code Online (Sandbox Code Playgroud)

然后这个接口有2个实现。一种是BubbleSort

@Component
@Qualifier("Bubble")
public class BubbleSort implements SortAlgorithem {

    Log log=LogFactory.getLog(BubbleSort.class);

    public int[] sort(int[] numbers) {
        log.info("Bubble sort is called");
        return numbers;
    }
}
Run Code Online (Sandbox Code Playgroud)

另一个是QuickSort

@Component
@Qualifier("Quick")
//@Primary
public class QuickSort implements SortAlgorithem{

    Log log= LogFactory.getLog(QuickSort.class);

    public int[] sort(int[] numbers) {
        log.info("Quick Sort is called");
        return numbers;
    }

}
Run Code Online (Sandbox Code Playgroud)

最后,当我调用我的应用程序时,它会抱怨以下消息:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
Run Code Online (Sandbox Code Playgroud)

我想知道......为什么@Qualifier注释不起作用?

sli*_*lim 8

您已使用@Autowiredand注释了一个字段@Qualifier,但您还创建了一个用于设置该字段的构造函数。

我认为 Spring 正在使用构造函数,但不会自动知道构造函数参数对应于带注释的字段。

因此,将注释移到构造函数声明中:

private SortAlgorithm sorter;

@Autowired 
public BinarySearchImpl(@Qualifier("quick") SortAlgorithm sorter) {
     this.sorter = sorter;
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用零参数构造函数,保留字段注释并让 Spring 使用反射注入。但是在我看来构造函数注入更好——它允许您干净地进行单元测试,而无需涉及 Spring 或反射。

正如其他答案指出的那样,还有其他方法可以消除自动装配 bean 的歧义——Spring 文档对它们进行了解释——但是使用像这样的限定符确实有效。


Shr*_*are 8

正确的做法:

public interface SortAlgorithem {
    public int[] sort(int[] arrayNumbers);
}

@Component("Bubble")
public class BubbleSort implements SortAlgorithem {
    Log log = LogFactory.getLog(BubbleSort.class);

    public int[] sort(int[] numbers) {
        log.info("Bubble sort is called");
        return numbers;
   }
}

@Primary
@Component("Quick")
public class QuickSort implements SortAlgorithem {
    Log log = LogFactory.getLog(QuickSort.class);

    public int[] sort(int[] numbers) {
        log.info("Quick Sort is called");
        return numbers;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你需要像这样使用你的实现:

@Autowired
@Qualifier(value = "Bubble")
private SortAlgorithem bubbleSort;

@Autowired
@Qualifier(value = "Quick")
private SortAlgorithem quickSort;
Run Code Online (Sandbox Code Playgroud)