Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@Qualifier Annotation in Spring is not working

I have just learnt Spring Framework and have been using Spring 2.5 for this learning. I have created three beans with these classes

Food.java

package com.spring.danipetrick;

public interface Food {
    void ingredients(); 
}

NasiGoreng.java

package com.spring.danipetrick;

public class NasiGoreng implements Food {

    public NasiGoreng() {

    }

    public void ingredients() {
        System.out.println("Rice, Coconut oil, Egg, Crackers");
    }

    @Override
    public String toString() {
        return "Nasi Goreng";
    }
}

Rendang.java

package com.spring.danipetrick;

public class Rendang implements Food {
    public void ingredients() {
        System.out.println("Beef, Coconut milk, spices");
    }

    @Override
    public String toString() {
        return "Rendang";
    }
}

PecintaKuliner.java

package com.spring.danipetrick;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class PecintaKuliner {

    @Autowired
    @Qualifier("nasigoreng")
    private Food food;

    @Autowired
    public void setFood(Food food) {
        this.food = food;
    }

    public Food getFood() {
        return this.food;
    }

    public void sayMaknyus() {
        System.out.println(food.toString() + " memang maknyus...");
    }
}

Xml configuration, qualifier-test.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans.xsd
     http://www.springframework.org/schema/context 
     http://www.springframework.org/schema/context/spring-context.xsd">

  <context:annotation-config />

  <bean id="bondan" class="com.spring.danipetrick.PecintaKuliner">
  </bean>

  <bean id="rendang" class="com.spring.danipetrick.Rendang"/>

  <bean id="nasigoreng" class="com.spring.danipetrick.NasiGoreng" />

</beans>

Finally, class with main method is QualifierTestMain.java:

package com.spring.danipetrick;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class QualifierTestMain {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("/qualifier-test.xml"); 

        PencintaKuliner bondan = (PencintaKuliner)context.getBean("bondan");
        bondan.sayMaknyus();
    }
}

When I run this project, I have an error like this

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.spring.danipetrick.Food] is defined: expected single matching bean but found 2: [rendang, nasigoreng]

Why @Qualifier annotation is not working in my case?

like image 597
Dani Petrick Avatar asked Nov 23 '13 06:11

Dani Petrick


People also ask

Can we use @bean and @qualifier together?

If we require the other bean at some injection point, we would need to specifically indicate it. We can do that via the @Qualifier annotation. For instance, we could specify that we want to use the bean returned by the johnEmployee method by using the @Qualifier annotation.

What is the use of @qualifier annotation in Spring?

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.

What does @qualifier do in spring boot?

One of the most important annotations in spring is @Qualifier annotation which is used to eliminate the issue of which bean needs to be injected.

What is the difference between @qualifier and Autowired?

The difference are that @Autowired and @Qualifier are the spring annotation while @Resource is the standard java annotation (from JSR-250) . Besides , @Resource only supports for fields and setter injection while @Autowired supports fields , setter ,constructors and multi-argument methods injection.


3 Answers

Both your method and field are annotated with @Autowired. As such, Spring will try to inject both. On one of the runs, it will try to inject

@Autowired
@Qualifier("nasigoreng")
private Food food;

which will work because the injection target is qualified.

The method however

@Autowired
public void setFood(Food food) {
    this.food = food;
}

does not qualify the injection parameter so Spring doesn't know which bean to inject.

Change the above to

@Autowired
public void setFood(@Qualifier("nasigoreng") Food food) {
    this.food = food;
}

But you should decide one or the other, field or setter injection, otherwise it is redundant and may cause errors.

like image 139
Sotirios Delimanolis Avatar answered Oct 23 '22 12:10

Sotirios Delimanolis


I tried with Spring 4.2.4. Problem resolved just by adding <context:annotation-config /> in configuration file.

like image 4
Nawanshu Avatar answered Oct 23 '22 12:10

Nawanshu


Try only removing @Autowired from setFood() in PecintaKuliner

like

@Autowired
@Qualifier("nasigoreng")
private Food food;

public void setFood(Food food) {
    this.food = food;
}
like image 3
Sandhu Santhakumar Avatar answered Oct 23 '22 12:10

Sandhu Santhakumar