Spring
June 3, 2020

M01 Q18 What is @Qualifier?

How does the @Qualifier annotation complement the use of @Autowired?

As you already know @Autowired is used in Spring to turn on the Spring Dependency Injection. Whenever you have @Autowired on the constructor or the setter method, Spring will search for the beans that are matching the types.

However, if few beans are matching the type and there is no way to tell if one bean should be injected or the other one. Spring doesn't know which bean should be injected then it will throw NoUniqueBeanDefinitionException.

To resolve this exception Spring needs to have some additional information. Either you can narrow the type or you can use @Qualifier.

@Qualifier annotation gives you additional control on which bean will be injected when multiple beans of the same type are found.

By adding additional information on which bean you want to inject, @Qualifier resolves issues with NoUniqueBeanDefinitionException.

You can use @Qualifier in three ways:

  • At injection point with bean name as a value
  • At injection and bean definition point
  • Custom Qualifier Annotation Definition

Now let's look into the code.

We have a service class with several dependencies that are injected with @Qualifier annotation.

If I remove one @Qualifier in the first example, Spring will throw an exception:

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.spring.module01.question18.bls.RecordsProcessor' available: expected single matching bean but found 2: dbRecordsProcessor,fileRecordsProcessor

In the details of this exception, we can see that there are two beans that matching type RecordsReader. This is because RecordsReader interface is implemented by two classes and each of this class is a Bean.

That's why you should use @Qualifier with a bean name you want to inject.

You can ask how I can use bean name without defining it. It is simple - Spring will generate the bean name based on the name of the class.

The second example is also using @Qualifier. However ed.here I am using a different name instead of relying on the bean name that will be automatically generated by Spring. Here I have used @Component value to set my custom name.

The third example is using @Qaulifier at the field point adn also @Qualifier at the definition point

And the last example is showing the custom annotation definition.

I have defined a custom annotation @RecordsValidatorType that extends @Qualifier and can be applied to field, method, parameter and type definition.

My annotation has a value field which can take enum RecordsValidatorMode