Ich habe einen @Autowired
Dienst, der innerhalb einer statischen Methode verwendet werden muss. Ich weiß, dass dies falsch ist, aber ich kann das aktuelle Design nicht ändern, da es viel Arbeit erfordern würde. Deshalb brauche ich dafür einen einfachen Hack. Ich kann mich nicht ändern randomMethod()
, um nicht statisch zu sein, und ich muss diese automatisch verdrahtete Bean verwenden. Irgendwelche Hinweise, wie das geht?
@Service
public class Foo {
public int doStuff() {
return 1;
}
}
public class Boo {
@Autowired
Foo foo;
public static void randomMethod() {
foo.doStuff();
}
}
Antworten:
Sie können dies tun, indem Sie einer der folgenden Lösungen folgen:
Verwenden des Konstruktors @Autowired
Dieser Ansatz erstellt die Bean, für die einige Beans als Konstruktorparameter erforderlich sind. Innerhalb des Konstruktorcodes legen Sie das statische Feld mit dem Wert fest, der als Parameter für die Konstruktorausführung erhalten wurde. Stichprobe:
Verwenden von @PostConstruct, um den Wert an ein statisches Feld zu übergeben
Die Idee hier ist, eine Bohne an ein statisches Feld zu übergeben, nachdem die Bohne bis zum Frühjahr konfiguriert wurde.
quelle
Sie müssen dies über den statischen Anwendungskontext-Accessor-Ansatz umgehen:
Anschließend können Sie statisch auf Bean-Instanzen zugreifen.
quelle
getBean
bevor der Kontext initialisiert wird (NPE) oder nachdem der Kontext mit seinen Beans zerstört wurde. Dieser Ansatz hat den Vorteil, dass der "hässliche" statische Kontextzugriff in einer Methode / Klasse enthalten ist.Sie können
@Autowired
eine Setter-Methode verwenden und ein neues statisches Feld festlegen.Wenn die Bean verarbeitet wird, fügt Spring eine
Foo
Implementierungsinstanz in das Instanzfeld einfoo
. Anschließend wird dieselbeFoo
Instanz auch in diesetStaticFoo()
Argumentliste eingefügt, mit der das statische Feld festgelegt wird.Dies ist eine schreckliche Problemumgehung und schlägt fehl, wenn Sie versuchen, sie zu verwenden,
randomMethod()
bevor Spring eine Instanz von verarbeitet hatBoo
.quelle
setStaticFoo()
das heißt, ohne denFoo
Parameter.Es ist scheiße, aber Sie können die Bohne über die
ApplicationContextAware
Schnittstelle erhalten. Etwas wie :quelle
Dies baut auf der Antwort von @ Pavel auf , um die Möglichkeit zu beseitigen, dass der Spring-Kontext beim Zugriff über die statische getBean-Methode nicht initialisiert wird:
Das wichtige Stück hier ist die
initContext
Methode. Es stellt sicher, dass der Kontext immer initialisiert wird. Beachten Sie jedoch, dassinitContext
dies ein Streitpunkt in Ihrem Code sein wird, wenn dieser synchronisiert wird. Wenn Ihre Anwendung stark parallelisiert ist (z. B. das Backend einer Site mit hohem Datenverkehr), ist dies möglicherweise keine gute Lösung für Sie.quelle
Verwenden Sie AppContext. Stellen Sie sicher, dass Sie eine Bean in Ihrer Kontextdatei erstellen.
quelle