Używam Dependency Injection na wiosnę już od jakiegoś czasu i rozumiem, jak to działa oraz jakie są zalety i wady korzystania z niego. Kiedy jednak tworzę nową klasę, często zastanawiam się - czy tą klasą powinien zarządzać Spring IOC Container?
I nie chcę mówić o różnicach między adnotacją @Autowired, konfiguracją XML, iniekcją seterów, iniekcją konstruktora itp. Moje pytanie jest ogólne.
Załóżmy, że mamy usługę z konwerterem:
@Service
public class Service {
@Autowired
private Repository repository;
@Autowired
private Converter converter;
public List<CarDto> getAllCars() {
List<Car> cars = repository.findAll();
return converter.mapToDto(cars);
}
}
@Component
public class Converter {
public CarDto mapToDto(List<Car> cars) {
return new ArrayList<CarDto>(); // do the mapping here
}
}
Najwyraźniej konwerter nie ma żadnych zależności, więc nie jest konieczne, aby został on automatycznie napisany. Ale dla mnie wygląda to lepiej jako autowired. Kod jest bardziej przejrzysty i łatwy do przetestowania. Jeśli napiszę ten kod bez DI, usługa będzie wyglądać następująco:
@Service
public class Service {
@Autowired
private Repository repository;
public List<CarDto> getAllCars() {
List<Car> cars = repository.findAll();
Converter converter = new Converter();
return converter.mapToDto(cars);
}
}
Teraz znacznie trudniej to przetestować. Co więcej, nowy konwerter zostanie utworzony dla każdej operacji konwersji, nawet jeśli zawsze jest w tym samym stanie, co wydaje się narzutem.
Istnieją pewne dobrze znane wzorce w Spring MVC: Kontrolery korzystające z usług i Usługi korzystające z repozytoriów. Następnie, jeśli repozytorium jest autowiredowane (którym zwykle jest), to usługa również musi być autowiredowana. I to jest całkiem jasne. Ale kiedy używamy adnotacji @Component? Jeśli masz jakieś statyczne klasy użytkowania (takie jak konwertery, mapery) - czy je autoryzujesz?
Czy starasz się, aby wszystkie klasy były automatycznie programowane? Wtedy wszystkie zależności klasowe są łatwe do wstrzyknięcia (ponownie, łatwe do zrozumienia i przetestowania). A może próbujesz uruchomić się automatycznie tylko wtedy, gdy jest to absolutnie konieczne?
Spędziłem trochę czasu na szukaniu ogólnych zasad dotyczących korzystania z automatycznego okablowania, ale nie mogłem znaleźć żadnych konkretnych wskazówek. Zwykle ludzie mówią o „czy używasz DI? (Tak / nie)” lub „jaki typ zastrzyku zależności preferujesz”, co nie odpowiada na moje pytanie.
Byłbym wdzięczny za wszelkie wskazówki dotyczące tego tematu!