Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring @Qualifier isn't working without @Primary [duplicate]

So, I am trying to learn my way with Spring Boot. I tried @Qualifier and @Autowired but it gives me the following error:

Parameter 0 of constructor in io.cptpackage.springboot.bootdemo.BinarySearch required a single bean, but 2 were found:

Even tho I have provided the right @Qualifier it doesn't work until one of the dependencies has a @Primary annotation, also the name reference doesn't work I to use @Primary or @Qualifier and you know that I am having the issue with the @Qualifier thing. The code is simple and as following.

@Component 
public class BinarySearch {

// Sort, Search, Return the result!
@Autowired
@Qualifier("quick")
Sorter sorter;

public BinarySearch(Sorter sorter) {
    super();
    this.sorter = sorter;
}

public int search(int[] numbersToSearchIn, int targetNumber) {
    sorter.sort(numbersToSearchIn);
    return targetNumber;
 } 
}

The first dependency:

@Component
@Qualifier("bubble")
public class BubbleSort implements Sorter {

    @Override
    public int[] sort(int[] targetArray) {
        System.out.println("Bubble sort!");
        return targetArray;
    }

}

The second dependency:

@Component
@Qualifier("quick")
public class QuickSort implements Sorter {

    @Override
    public int[] sort(int[] targetArray) {
        System.out.println("Quick Sort!");
        return targetArray;
    }

}

Also why is autowiring by name isnot working?

like image 448
CptPackage Avatar asked Aug 28 '17 01:08

CptPackage


People also ask

Can we use @qualifier and @primary together?

We can use @Qualifier and @Primary for the same bean. Use @Qualifier to inject specific bean otherwise Spring injects bean by default which is annotated with @Primary.

What is difference between @primary and @qualifier annotation?

The @Primary annotation sets the bean preference and it is used with the @Bean or @Component etc stereotype annotations. On the other hand, @Qualifier is usually used with @Autowired or @Inject etc annotations.

Can we use @qualifier and @bean together?

NOTE: if you are creating bean with @Bean, it will be injected byType if there is duplicates then it will injected byName. we no need to mention @Bean(name="bmwDriver") . so you can directly use qualifier("bmwDriver") wherever you need in classes.

What is the Java equivalent of Spring @autowired and @qualifier annotation?

The @Qualifier annotation is used to resolve the autowiring conflict, when there are multiple beans of same type. The @Qualifier annotation can be used on any class annotated with @Component or on methods annotated with @Bean . This annotation can also be applied on constructor arguments or method parameters.


2 Answers

Using the below piece of code

@Autowired
@Qualifier("quick")

Sorter sorter;

you are telling spring the instance of sorter should be qualified for "quick" bean. But in the below constructor:

public BinarySearch(Sorter sorter) {
    super();
    this.sorter = sorter;
}

you are not informing spring to which instance of Sorter should be used. As there are 2 bean qualifying for this so spring is throwing error. So either you put @Qualified("quick") annotation before the Sorter arg or remove the Sorter arg from the constructor. Hope this helps.

like image 41
imnitesh Avatar answered Sep 17 '22 23:09

imnitesh


@Qualifier is an annotation to specify the bean that you need to inject, it works together with @Autowired.

ff you need to specify the name of a component just put a name @Component("myComponent") and after that when you need to inject it use @Qualifier("myComponent")

For your question try this:

Instead of:

@Component
@Qualifier("bubble")
public class BubbleSort implements Sorter {

Use this:

@Component("quick")
public class BubbleSort implements Sorter {

And finally define one way to inject the bean for example:

Option 1: constructor parameter

@Component 
public class BinarySearch {

// Sort, Search, Return the result!
private final Sorter sorter;

public BinarySearch(@Qualifier("quick")Sorter sorter) {
    super();
    this.sorter = sorter;
}

Option 2 as a class member

@Component 
public class BinarySearch {

// Sort, Search, Return the result!
@Autowired
@Qualifier("quick")
Sorter sorter;

public BinarySearch() {
    super();

}
like image 118
Daniel C. Avatar answered Sep 19 '22 23:09

Daniel C.