Почему передача значений Autowired полей в качестве параметров метода базового класса — это антипаттерн?
Допустим есть сервисные классы(1), в которые инжектированы как поля - другие сервисные классы(2). Все сервисные классы 1 выполняют одно и то же действие, с помощью соответствующего(у каждого свой) сервисного класса 2. Было принято решение выделить это повторяющееся действие в метод базового класса сервисных классов 1, а также выделить соответствующий интерфейс, который должны реализовать все классы 2. Метод базового класса принимает на вход этот интерфейс, т.е. объект класса 2.
Коллеги считают такой подход антипаттерном, а именно - передачу инжектированных объектов в методы базового класса. Порыскав по интернету, ничего на этот счет не обнаружил. Хотелось бы услышать мнение со-стороны.
Правильно считают. Вы должны заинжектить через интерфейс объекта2 в базовом сервисном классе и там его использовать. А вот уже при объявлении бина сервисного класса указать что туда будет инжектиться.
обычно это делают через аннотацию @Required над сеттером нужного бин-поля
а чтобы передать при таком раскладе из сервисного класса в родительский класс нужный бин, делаете @Autowired в конструкторе сервисного класса и после super() вызываете setMyBean(mybean)
Аннотации @Required применяется к методам-сеттерам и означает, что значение метода должно быть установлено в XML-файле. Если этого не будет сделано, то мы получим BeanInitializationException.
Не очень понятно, как это применимо к описываемой ситуации.
Дмитрий: где в документации про XML? это такая же настройка бина, только через JavaConfig
import demo.toster.BeanA;
import demo.toster.BeanB;
import demo.toster.IBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Config {
@Bean
public IBean beanA() {
return new BeanA();
}
@Bean
public IBean beanB() {
return new BeanB();
}
@Bean
public AbstractService serviceA(@Qualifier("beanA") IBean bean) {
final ServiceImpl service = new ServiceImpl();
service.setBean(bean);
return service;
}
@Bean
public AbstractService serviceB(@Qualifier("beanB") IBean bean) {
final ServiceImpl service = new ServiceImpl();
service.setBean(bean);
return service;
}
}