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

时间:2017-11-13 10:38:33

标签: 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;
    }

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

public interface SortAlgorithem {

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

}

然后这个接口有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;
    }
}

另一个是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;
    }

}

最后,当我打电话给我的应用时,它抱怨这条消息:

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

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

6 个答案:

答案 0 :(得分:2)

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

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

所以将注释移到构造函数声明中:

private SortAlgorithm sorter;

@Autowired 
public BinarySearchImpl(@Qualifier("quick") SortAlgorithm sorter) {
     this.sorter = sorter;
}

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

正如其他答案所指出的,还有其他方法可以消除自动装配的bean的歧义 - 而Spring文档会解释所有这些 - 但是使用这样的限定符确实有用。

答案 1 :(得分:1)

尝试

@Component("qualifier_name")

答案 2 :(得分:0)

您必须声明您的组件:

@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;
    }
}

@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;
    }

}

这可以解决您的问题。

答案 3 :(得分:0)

嗨,抱歉参加晚会。 我有2个服务类正在实现这样的单个接口,所以 我已经使用@Component("name")完成了此任务,并且有效。 为什么@Qualifier("name")没用还是个谜?

代码:

@Service("signup")
//@Qualifier("signup")
public class SignUpGenerator implements ITestCaseGenerator {

}




@Component
public class SelUtil {

    @Autowired
    @Qualifier("login")
    ITestCaseGenerator login;

    @Autowired
    @Qualifier("signup")
    ITestCaseGenerator signUp;

}

答案 4 :(得分:0)

正确的方法:

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;
    }
}

然后您需要使用以下实现:

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

@Autowired
@Qualifier(value = "Quick")
private SortAlgorithem quickSort;

答案 5 :(得分:0)

在使用@RequiredArgsConstructor注释时,我遇到了这个问题,不得不将其删除(并根据@slim answer使用带有@Qualifier注释的手动构造函数)。