Tnadev
Tnadev

Reputation: 10112

NoSuchBeanDefinitionException: No unique bean of type is define. While two beans of same type

This is first time I am using @autowiring, I have a example.

I want to use Autowiring by TYPE , SO that at Run time container injects appropriate Object and calls appropriate bean/method.

1.INTERFACE

  public interface Calculator {

    public int add(int a,int b);
}

2.First Class

public class CalculatorImpl implements Calculator {

public int add(int a, int b) {
    // TODO Auto-generated method stub
    int result=a+b;

    return result;
}

}

3.Second Class

public class CalculatorImpl2 implements Calculator{

public int add(int a, int b) {
    // TODO Auto-generated method stub
    int result=a-b;

    return result;
}

}

4.REST CLASS

@Component
@Path("/calc")
    public class CalculationService {
    @Autowired
    Calculator calculator;

    @GET
    @Path("/add/{a}/{b}/")
@Qualifier("calculatorImpl")
    @Produces("text/plain")
    public Response serveAdd(@PathParam("a") int a,
            @PathParam("b") int b)
    {

        int result= calculator.add(a, b);

        return Response.status(200).entity(String.valueOf(result)).build();

    }


    @GET
    @Path("/sub/{a}/{b}")
@Qualifier("calculatorImpl2")
    public Response serveSub(@PathParam("a") int a,
            @PathParam("b") int b)
    {
        int result= calculator.add(a, b);

        return Response.status(200).entity(String.valueOf(result)).build();


    }
}

5.APPLICATION-CONTEXT.xml

<context:component-scan base-package="com.veke.rest" />

 <bean id="calculatorImpl" 
                  class="com.veke.calcImpl.CalculatorImpl"  autowire="byType"/>


  <bean id="calculatorImpl2" 
                  class="com.veke.calcImpl.CalculatorImpl2"  autowire="byType"/>

                  </beans>

ERROR:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'calculationService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.veke.calc.Calculator com.veke.rest.CalculationService.calculator; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.veke.calc.Calculator] is defined: expected single matching bean but found 2: [calculatorImpl, calculatorImpl2]

Have I done correct things? Or I am wrong.

I have done this with my understanding of @autowiring.

Many Thanks :)

Edit: @Qualifier is solution for this problem.(As i Have two beans with same type in context). Its used to solve ambiguity problem. @Autowired is by Type.

Upvotes: 1

Views: 7059

Answers (2)

Darshan Lila
Darshan Lila

Reputation: 5868

Try following: Change following files:

APPLICATION-CONTEXT.xml :

<context:component-scan base-package="com.veke.rest" />

 <bean name="Impl1" id="calculatorImpl" 
                  class="com.veke.calcImpl.CalculatorImpl"  autowire="byType"/>


  <bean name="Impl2" id="calculatorImpl2" 
                  class="com.veke.calcImpl.CalculatorImpl2"  autowire="byType"/>

                  </beans>

Rest Class :

@Component
@Path("/calc")
    public class CalculationService {
    @Autowired
    @Qualifier("Impl1"); //<-- qualifier used here.
    Calculator calculator;

    @Autowired
    @Qualifier("Impl2"); //<-- qualifier used here.
    Calculator calculator2;


    @GET
    @Path("/add/{a}/{b}/")
    @Produces("text/plain")
    public Response serveAdd(@PathParam("a") int a,
            @PathParam("b") int b)
    {

        int result= calculator.add(a, b);

        return Response.status(200).entity(String.valueOf(result)).build();

    }


    @GET
    @Path("/sub/{a}/{b}")
    public Response serveSub(@PathParam("a") int a,
            @PathParam("b") int b)
    {
        int result= calculator2.add(a, b);

        return Response.status(200).entity(String.valueOf(result)).build();


    }
}

Upvotes: 0

Mithun
Mithun

Reputation: 8067

You cannot have just one Calculator instance variable and make it behave as both CalculatorImpl and CalculatorImpl2. You need to make the following changes:

In CalculationService:

@Autowired
@Qualifier("Impl1")
Calculator calculator;

@Autowired
@Qualifier("Impl2")
Calculator calculator2;

Then you can use these instance variables in the respective methods.

Upvotes: 3

Related Questions