Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring @Autowired and @Qualifier [closed]

Tags:

java

spring

Is it auto detected with @Autowired?
Is it dependency injection by name when @Qualifier is used?
How can we do setter and constructor injection using these annotations?

like image 888
Dhananjaya Senanayake Avatar asked Nov 27 '16 15:11

Dhananjaya Senanayake


People also ask

What is the java equivalent of Spring @autowired and @qualifier annotation?

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 is the difference between @autowired and @qualifier?

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.

What is the actual use of @autowired @qualifier @component annotation?

There may be a situation when you create more than one bean of the same type and want to wire only one of them with a property. In such cases, you can use the @Qualifier annotation along with @Autowired to remove the confusion by specifying which exact bean will be wired.

Can we use @qualifier and @primary together?

We can use @Qualifier and @Primary for the same bean. Use @Qualifier to inject specific bean otherwise Spring injects bean by default which is annotated with @Primary.


2 Answers

You can use @Qualifier along with @Autowired. In fact spring will ask you explicitly select the bean if ambiguous bean type are found, in which case you should provide the qualifier

For Example in following case it is necessary provide a qualifier

@Component @Qualifier("staff")  public Staff implements Person {}  @Component @Qualifier("employee")  public Manager implements Person {}   @Component public Payroll {      private Person person;      @Autowired     public Payroll(@Qualifier("employee") Person person){           this.person = person;     }  } 

EDIT:

In Lombok 1.18.4 it is finally possible to avoid the boilerplate on constructor injection when you have @Qualifier, so now it is possible to do the following:

@Component @Qualifier("staff")  public Staff implements Person {}  @Component @Qualifier("employee")  public Manager implements Person {}   @Component @RequiredArgsConstructor public Payroll {    @Qualifier("employee") private final Person person; } 

provided you are using the new lombok.config rule copyableAnnotations (by placing the following in lombok.config in the root of your project):

# Copy the Qualifier annotation from the instance variables to the constructor # see https://github.com/rzwitserloot/lombok/issues/745 lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier 

This was recently introduced in latest lombok 1.18.4.

  • The blog post where the issue is discussed in detail
  • The original issue on github
  • And a small github project to see it in action

NOTE

If you are using field or setter injection then you have to place the @Autowired and @Qualifier on top of the field or setter function like below(any one of them will work)

public Payroll {    @Autowired @Qualifier("employee") private final Person person; } 

or

public Payroll {    private final Person person;    @Autowired    @Qualifier("employee")    public void setPerson(Person person) {      this.person = person;    }  } 

If you are using constructor injection then the annotations should be placed on constructor, else the code would not work. Use it like below -

public Payroll {      private Person person;      @Autowired     public Payroll(@Qualifier("employee") Person person){           this.person = person;     }  } 
like image 160
kuhajeyan Avatar answered Sep 26 '22 04:09

kuhajeyan


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.

Ex:-

public interface Vehicle {      public void start();      public void stop(); } 

There are two beans, Car and Bike implements Vehicle interface

@Component(value="car") public class Car implements Vehicle {       @Override      public void start() {            System.out.println("Car started");      }       @Override      public void stop() {            System.out.println("Car stopped");      }  }  @Component(value="bike") public class Bike implements Vehicle {       @Override      public void start() {           System.out.println("Bike started");      }       @Override      public void stop() {           System.out.println("Bike stopped");      } } 

Injecting Bike bean in VehicleService using @Autowired with @Qualifier annotation. If you didn't use @Qualifier, it will throw NoUniqueBeanDefinitionException.

@Component public class VehicleService {      @Autowired     @Qualifier("bike")     private Vehicle vehicle;      public void service() {          vehicle.start();          vehicle.stop();     } } 

Reference:- @Qualifier annotation example

like image 30
Anil Nivargi Avatar answered Sep 24 '22 04:09

Anil Nivargi