Wstrzykiwanie zależności, które opisywaliśmy w poprzednim rozdziale (
Wstrzykiwanie zależności - podstawy) 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 - podstawy).
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.
Nasza rekomendacja
Dobrze jest nie nadużywać adnotacji @Bean w celu inicjalizacji
włanych obiektów. Najlepiej jest tworzyć klasy oznaczone adnotacjami @Component, @Controller,
@Service,
@Repository (tak aby klasy wypełniały przeznaczenie tych adnotacji) i tym samym pozostawić inicjalizację obiektów frameworkowi. Oczywiście w pewnych
przypadkach jest to niemożliwe, np. gdy chcemy stworzyć obiekt klasy dostępnej w zewnętrznej
bibliotece, która nie jest komponentem Springa. Wówczas pozostaje nam użycie wspomnianej adnotacji.
Używamy w StartAPPa
Ciekawostką związana z aplikacją jest to, że stosujemy adnotację @Qualifier, aby czasem odróżnić niektóre szczegóły implementacji
w aplikacji dostępnej online od tej dostępnej w Kursie Aplikacji Web - Mega pakiet.
Na przykład, w aplikacji online używamy innych ścieżek konfiguracyjnych,
bądź też łączymy się do innej bazy danych niż w kursie (kurs ma domyślnie wbudowaną bazę).
Jest to według nas bardzo ciekawy przypadek użycia i dlatego postanowiliśmy o tym wspomnieć.
Niemniej przykład opisany wyżej (SimpleItemServiceImpl i CompositeItemServiceImpl) nie
pochodzi dokładnie z naszego kodu źródłowego i został specjalnie przygotowany na potrzeby tego kursu. Warto jednak zauważyć, że bazuje on na interfejsie
ItemService, który ze względu na swoje znaczenie tematyczne znajdziecie w większości naszych kursów.
[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.
Linki
https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-annotation-config
https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/factory/annotation/Qualifier.html
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Bean.html