Dobra praktyka - rejestruj najbardziej szczególny typ beana w Spring!
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).
public class ExampleClass implements A, B {
}
public class FirstClass {
private final A a;
}
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.
@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?
@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.