Spring @Autowired и @Qualifier

Это автоматически определяется с @Autowired? Это внедрение зависимостей по имени, когда используется @Qualifier? Как мы можем сделать инъекцию сеттера и конструктора, используя эти аннотации?

Ответ 1

Вы можете использовать @Qualifier вместе с @Autowired. Фактически, Spring попросит вас явно выбрать компонент, если обнаружен неоднозначный тип компонента, и в этом случае вы должны предоставить квалификатор

.Например, в следующем случае необходимо предоставить квалификатор

@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:

В Lombok 1.18.4, наконец, можно избежать шаблона при внедрении конструктора, когда у вас есть @Qualifier, поэтому теперь можно сделать следующее:

@Component
@Qualifier("staff") 
public Staff implements Person {}

@Component
@Qualifier("employee") 
public Manager implements Person {}


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

при условии, что вы используете новое правило lombok.config copyableAnnotations из правила lombok (поместив следующее в lombok.config в корне вашего проекта):

# 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

Это было недавно введено в последней версии lombok 1.18.4.

Примечание

Если вы используете инъекцию поля или сеттера, тогда вы должны поместить @Autowired и @Qualifier поверх функции поля или сеттера, как показано ниже (любой из них будет работать)

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

или

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

Если вы используете инъекцию конструктора, аннотации должны быть помещены в конструктор, иначе код не будет работать. Используйте его, как показано ниже -

public Payroll {

    private Person person;

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

}

Ответ 2

Аннотация @Qualifier используется для разрешения конфликта автопроводки, когда существует несколько бинов одного типа.

Аннотация @Qualifier может использоваться для любого класса, аннотированного @Component или для методов, аннотированных @Bean. Эта аннотация также может применяться к аргументам конструктора или параметрам метода.

Пример: -

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

Существует два компонента: Car и Bike реализуют интерфейс автомобиля.

@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");
     }
}

Внедрение компонента Bike Bean в VehicleService с использованием @Autowired с аннотацией @Qualifier. Если вы не использовали @Qualifier, он выдаст исключение NoUniqueBeanDefinitionException.

@Component
public class VehicleService {

    @Autowired
    @Qualifier("bike")
    private Vehicle vehicle;

    public void service() {
         vehicle.start();
         vehicle.stop();
    }
}

Ссылка: - пример аннотации @Qualifier

Ответ 3

@Autowired для автоматического подключения (или поиска) по типу
@Qualifier для автоматического подключения (или поиска) по имени
Другой альтернативный вариант для @Qualifier - @Primary

@Component
@Qualifier("beanname")
public class A{}

public class B{

//Constructor
@Autowired  
public B(@Qualifier("beanname")A a){...} //  you need to add @autowire also 

//property
@Autowired
@Qualifier("beanname")
private A a;

}

//If you don't want to add the two annotations, we can use @Resource
public class B{

//property
@Resource(name="beanname")
private A a;

//Importing properties is very similar
@Value("${property.name}")  //@Value know how to interpret ${}
private String name;
}

больше о @value