Wstrzykiwanie zależności, które opisywaliśmy w poprzednim rozdziale (
Wstrzykiwanie zależności: DI & IoC) nie wyczerpuje
w pełni tematu zarówno w kontekście adnotacji
@Autowired jak i innych
możliwości wstrzykiwania.
Adnotacja @Qualifier
Kontynuując wątek adnotacji
@Autowired musimy odpowiedzieć na jedno
pytanie. Co się stanie w przypadku gdy mamy dwie klasy implementujące ten sam interfejs i używając tego
interfejsu chcemy wstrzyknąć konkretnie jedną z tych klas? Mamy więc interfejs:
Następnie mamy dwie klasy implementujące ten sam interfejs:
Spróbujmy zatem wstrzyknąć
ItemService używając jego konkretnej
implementacji -
SimpleItemServiceImpl. Aby Spring wiedział, że ma
wybrać właśnie tą klasę należy ją opisać dodatkowo adnotacją
@Qualifier.
Jako atrybut podajemy
nazwę zdefiniowaną
dla konkretnej klasy serwisu:
W ten sposób wstrzykniemy konkretną implementację interfejsu
ItemService
do klasy
ItemController, czyli nasz cel został osiągnięty.
Dodajmy jeszcze dlaczego wstrzykujemy
itemService przez pole, a nie tak jak zwykle zalecamy - przez konstruktor.
Związane jest to z tym, że nie planujemy pisać testów jednostkowych dla kontrolerów (tylko dla serwisów), a to ma kluczowe znaczenie
w kontekście wyboru metody wstrzykiwania (dla zainteresowanych zapraszamy do rozdziału
Wstrzykiwanie zależności: DI & IoC).
Adnotacja @Bean
Kolejnym rozwiązaniem umożliwiającym wstrzyknięcie obiektu jest wykorzystanie adnotacji
@Bean. W takim przypadku jeśli jesteśmy w klasie oznaczonej adnotacją
@Configuration, możemy zdefiniować jaki obiekt i w jaki sposób chcemy
stworzyć (w naszym przypadku
PasswordEncoder). W tym momencie Spring uruchomi naszą metodę i
zarejestruje obiekt w kontenerze. Wtedy będziemy mogli go wstrzyknąć w innym miejscu korzystając np. z
adnotacji
@Autowired.
Rekomendacja
Zaleca się unikanie nadmiernego stosowania adnotacji @Bean do inicjowania własnych obiektów w Spring Framework.
Optymalnym podejściem jest definiowanie klas z wykorzystaniem adnotacji takich jak
@Component, @Controller, @Service, @Repository.
Taki wybór adnotacji powinien odzwierciedlać intencję i funkcjonalność danej klasy,
pozwalając tym samym frameworkowi na efektywne zarządzanie procesem inicjalizacji obiektów.
Istnieją jednak sytuacje, w których bezpośrednie wykorzystanie @Bean staje się koniecznością, na przykład przy
integracji z klasami z zewnętrznych bibliotek, które nie są w naturalny sposób komponentami Springa. W takich
przypadkach, stosowanie @Bean pozwala na precyzyjną konfigurację i zarządzanie instancjami tych klas w
kontenerze aplikacji Spring, zapewniając pełną kontrolę nad ich cyklem życia i zależnościami.
Praktyka
W ramach naszej aplikacji wykorzystujemy adnotację @Qualifier w celu dostosowania niektórych
aspektów implementacji pomiędzy wersją online a tą prezentowaną w ramach kursu "Kurs Aplikacji Web -
Mega pakiet". Dzięki tej technice możemy na przykład stosować różne ścieżki konfiguracyjne lub
łączyć się z innymi bazami danych – w wersji kursu wykorzystujemy wbudowaną bazę danych, podczas gdy
w aplikacji online konfiguracja ta jest inna. Uważamy, że ten sposób wykorzystania @Qualifier jest
interesującym przypadkiem użycia, wartym wspomnienia.
Autor: Jarek Klimas
Data: 03 stycznia 2024
Labele: Backend, Podstawowy, Java
Czy informacje, które otrzymałeś, były pomocne?
Jeśli tak, zapraszam Cię do podarowania mi kawy.
[TEORIA i PRAKTYKA] Strefa doładowania wiedzy
W tej strefie znajdziesz wszystko co niezbędne, aby komfortowo uczyć się Springa.
Doskonale opisany kod nie zawiera zbędnych komplikacji, tylko samą esencję w postaci praktycznych przykładów.
Tutaj odnajdziesz wszystko co jest istotne w danym temacie. Otrzymujesz pakiet złożony z kilku projektów
wraz z obszernym wytłumaczeniem kodu.
Topowe Materiały
Spring IO: Using the @Bean Annotation
Spring IO: Fine-tuning Annotation-based Autowiring with Qualifiers
Spring IO: The IoC Container
Spring IO: Dependency Injection
Baeldung: Intro to Inversion of Control
Baeldung: Spring Dependency Injection
Udemy: [NEW] Spring Boot 3, Spring 6 & Hibernate for Beginners — polskie napisy