Reputation: 10112
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
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
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