Close

Spring - Inject Bean by name and using @Qualifier

[Updated: Sep 2, 2016, Created: Dec 3, 2015]

Specifying an unique name for @Bean annotation is necessary if

  1. the configuration provides more than one implementations for a bean
  2. or if we want to inject bean instances by name rather than by type.

To match a named bean to an injection point (or in other words to qualify a bean to an injection point), the bean's property name (at the injection point) should match with the bean definition name.


Matching bean by using @Qualifier

Alternative to the way of matching and injecting beans by property names, we can use annotation @Qualifier at injection point.

We can also choose to use @Qualifier at bean definition instead of defining/using a bean's name.

@Qualifer can be specified at field or parameter.





Fixing by using @Qualifier at both places:


Example Project

Dependencies and Technologies Used:

  • Spring Context 4.2.3.RELEASE: Spring Context.
  • JDK 1.8
  • Maven 3.0.4

Inject Bean By Name Example Select All Download
  • spring-inject-bean-by-name
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • client
                • service
                  • impl

NoUniqueBeanDefinitionException

The @Autowired annotation tells Spring where the Injection Point is (i.e. where an injection needs to occur). On finding such injection point, Spring tries to find a configured bean (configured via @Bean) of the same type, if it finds such bean, it injects it to the injection point. If it finds two or more such beans, we will get an NoUniqueBeanDefinitionException. To avoid the exception, we have to use the @Qualifier annotation as we have seen in the above example.


In above example if we remove name element from both methods annotated with @Bean and remove the @Qualifier annotation from the injection point in OrderServiceClient, we will have following exception:

org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type  [com.logicbig.example.service.OrderService] is defined:
expected single matching bean but found 2:
orderServiceByProvider1,orderServiceByProvider2


Use of a qualifier shouldn't tie to an implementation specific 'name'

Some people may argue the usage of a Qualifier. The point could be, why we have to put a qualifier name to the application code (which seems to be tied to a particular implementation)? Well, qualifier should not be tied to implementation details if we use it wisely.

Let's consider our above example again. Assume the Qualifier with name OrderServiceA is meant to show some extended details about each orders. Whereas, OrderServiceB just shows the order summary. In that sense the application code should be in full control, whether it wants to show extended details or just summary. So the name of the Qualifier should be assigned in a business logic sense but not in implementation sense. There might still be multiple implementations of summary or extended order details available by some other providers which are not wired yet, but can be used anytime we want to. In that case, our qualifier will stay the same without affecting application logic, we just have to wire a different bean per our needs.

Based on above explanation, we should also rename our example qualifiers appropriately to something like OrderExtendedService and OrderSummaryService.

See Also