Mam @Autowired
usługę, z której należy korzystać w ramach metody statycznej. Wiem, że to źle, ale nie mogę zmienić obecnego projektu, ponieważ wymagałoby to dużo pracy, więc potrzebuję do tego prostego hacka. Nie mogę zmienić się randomMethod()
na niestatyczny i muszę użyć tej automatycznej fasoli. Jakieś wskazówki, jak to zrobić?
@Service
public class Foo {
public int doStuff() {
return 1;
}
}
public class Boo {
@Autowired
Foo foo;
public static void randomMethod() {
foo.doStuff();
}
}
Odpowiedzi:
Możesz to zrobić, wykonując jedno z rozwiązań:
Korzystanie z konstruktora @Autowired
To podejście spowoduje skonstruowanie fasoli wymagającej pewnych ziaren jako parametrów konstruktora. W kodzie konstruktora ustawiasz pole statyczne z wartością otrzymaną jako parametr do wykonania konstruktora. Próba:
Użycie @PostConstruct do przekazania wartości do pola statycznego
Pomysł polega na przekazaniu fasoli na statyczne pole po skonfigurowaniu fasoli na wiosnę.
źródło
Musisz obejść ten problem za pomocą metody dostępu do kontekstu aplikacji statycznej:
Następnie możesz uzyskać dostęp do instancji bean w sposób statyczny.
źródło
getBean
przed zainicjowaniem kontekstu (NPE) lub po zniszczeniu kontekstu z jego fasolami. Takie podejście ma tę zaletę, że „brzydki” dostęp do kontekstu statycznego jest zawarty w jednej metodzie / klasie.To, co możesz zrobić, to
@Autowired
metoda ustawiająca i ustawić nowe pole statyczne.Gdy ziarno zostanie przetworzone, Spring wstrzyknie
Foo
instancję implementacji do pola instancjifoo
. Następnie wstrzyknie to samoFoo
wystąpienie dosetStaticFoo()
listy argumentów, która zostanie użyta do ustawienia pola statycznego.Jest to okropne obejście i zakończy się niepowodzeniem, jeśli spróbujesz użyć go,
randomMethod()
zanim Spring przetworzy wystąpienieBoo
.źródło
setStaticFoo()
to jest bezFoo
parametru.To jest do bani, ale możesz zdobyć fasolę za pomocą
ApplicationContextAware
interfejsu. Coś jak :źródło
Opiera się to na odpowiedzi @ Pavel , aby rozwiązać problem braku inicjalizacji kontekstu Spring podczas uzyskiwania dostępu ze statycznej metody getBean:
Ważnym elementem jest tutaj
initContext
metoda. Zapewnia, że kontekst zawsze zostanie zainicjowany. Ale pamiętaj, żeinitContext
będzie to punkt sporny w twoim kodzie, ponieważ jest zsynchronizowany. Jeśli Twoja aplikacja jest mocno zrównoleglona (na przykład: zaplecze witryny o dużym ruchu), może to nie być dobre rozwiązanie dla Ciebie.źródło
Użyj AppContext. Upewnij się, że tworzysz fasolę w swoim pliku kontekstowym.
źródło