Я заметил, что аннотация @Qualifier
не работает с переменной-членом final
.
В приведенном ниже коде
Vehicle
переменная-член Person
объявлена как final
, возникает исключение;vehicle
равно нулю).Кто-нибудь может объяснить, почему?
// 2 Vehicle beans are annotated by @Qualifier;
@Configuration
public class Config
{
@Bean
@Qualifier("vehicle1")
Vehicle vehicle1() {
var veh = new Vehicle();
veh.setName("Benz");
return veh;
}
@Bean
@Qualifier("vehicle2")
Vehicle vehicle2() {
var veh = new Vehicle();
veh.setName("BMW");
return veh;
}
}
// Person has a final member variable Vehicle
@Component
@Data
public class Person
{
private String name = "Mike";
@Qualifier("vehicle2")
private final Vehicle vehicle;
}
Springboot жалуется на NoUniqueBeanDefinitionException:
- Нет подходящего компонента типа «project1.Vehicle»: ожидается один соответствующий компонент, но найдено 2: транспортное средство1, транспортное средство2
Проблема тесно связана с ломбоком, что встречается довольно часто.
Если вы используете IntelliJ, перейдите в каталог сборки проекта, чтобы открыть файл класса.
Обработанный класс:
@Component
public class Person {
private String name = "Mike";
@Qualifier("vehicle2")
private final Vehicle vehicle;
public Person(final Vehicle vehicle) {
this.vehicle = vehicle;
}
...
}
Мы видим, что в данном случае внедрение осуществляется через конструктор, а @Qualifier
игнорируется. Следовательно, мы увидим NoUniqueBeanDefinitionException
, поскольку мы не указываем, какой компонент использовать.
На этот раз обработанный класс:
@Component
public class Person {
private String name = "Mike";
@Qualifier("vehicle2")
private Vehicle vehicle;
public Person() {
}
...
}
vehicle
на этот раз не появляется в конструкторе, и нет @Autowired
для `транспортного средства, поэтому впрыск не выполняется, и он равен нулю.
Начнем с того, что не принято использовать @Data
с компонентом Spring, @Data
обычно используется DTO. И в пользу внедрения конструктора я изменю Person
, как показано ниже.
@Component
public class Person {
private String name = "Mike";
private final Vehicle vehicle;
public Person(@Qualifier("vehicle2") Vehicle vehicle) {
this.vehicle = vehicle;
}
// ... getter setter omitted
}
Отличный ответ - не только ответ, но и подход к нему и способ решения проблемы!