Pewnie tworząc beany nie raz trafiłeś na sytuację, w której rozpatrywana klasa implementuje więcej niż jeden interfejs. Okazuje się, że najlepszą metodą rejestrowania takiego beana jest rejestrowanie go jako typu najbardziej specyficznego (sekcja TIP).
1
2
public class ExampleClass implements A, B {
}
1
2
3
4
5
public class FirstClass {
private final A a;
}
1
2
3
4
5
public class SecondClass {
private final B b;
}
Załóżmy, że mamy sytuację jak powyżej. W przykładzie istnieją dwa kontrakty w postaci interfejsów A
i B
. Klasa FirstClass
zależy od kontraktu A
, natomiast SecondClass
od B
. Zwieńczeniem tych dwóch kontraktów jest klasa ExampleClass
. Po tym przedstawieniu pora wziąć się na zarejestrowanie instancji tych klas jako beany.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Configuration(proxyBeanMethods = false)
public class SpecificTypeConfiguration {
@Bean
public FirstClass firstClass(A a) {
return new FirstClass(a);
}
@Bean
public SecondClass secondClass(B b) {
return new SecondClass(b);
}
@Bean
public ExampleClass exampleClass() {
return new ExampleClass();
}
}
Przy tej okazji odsyłam do wpisu na temat @Configuration
, gdzie wyjaśnione zostało działanie proxyBeanMethods = false
. Dobra, z powyższej konfiguracji najistotniejsza jest rejestracja beana exampleClass
. W myśl wskazówki z dokumentacji Springa zapisałem najbardziej specyficzny typ, czyli nie A
ani B
tylko ExampleClass
. Próba uruchomienia aplikacji powinna zakończyć się sukcesem. I tak też jest! Natomiast co by się stało w przypadku, gdyby ten typ był tylko jednym z interfejsów?
1
2
3
4
5
6
7
8
9
@Bean
public A exampleClass() {
return new ExampleClass();
}
@Bean
public SecondClass secondClass(B b) {
return new SecondClass(b);
}
O dziwo aplikacja wstaje! Zależność dla SecondClass
w postaci B
została spełniona pomimo ostrzeżenia IntelliJ jakie można zauważyć przed uruchomieniem serwisu:
Could not autowire. No beans of ‘B’ type found.
Wychodzi na to, że Spring potrafi sobie poradzić z takim “problemem” (przykład był uruchamiany na wersji 3.3.2 Spring Boot - być może wcześniejsze wersje Springa nie posiadały takiego mechniazmu). Jednak zachęcam do stosowania się do wskazówki znajdującej się w dokumentacji. To podejście wydaje się logiczniejsze, a przy okazji IDE nie będzie nas wprowadzało w błąd o nieistniejącej zależności.