Ich blieb bei einem einfachen Refactoring von einfachem Java bis zum Frühling. Anwendung hat ein "Container" -Objekt, das seine Teile zur Laufzeit instanziiert. Lassen Sie mich mit dem Code erklären:
%Vor%Grundsätzlich bittet ein Container während eines Ladevorgangs ein externes System, ihm Informationen über Anzahl und Konfiguration jedes RuntimeBeans zu geben, und dann erstellt er Beans entsprechend der angegebenen Spezifikation.
Das Problem ist: normalerweise wenn wir im Frühling machen
%Vor%unser Objekt ist vollständig konfiguriert und hat alle Abhängigkeiten injiziert. Aber in meinem Fall muss ich einige Objekte instanziieren, die auch eine Abhängigkeitsinjektion benötigen, nachdem ich die load () Methode ausgeführt habe. Wie kann ich das erreichen?
Ich verwende Java-basierte Konfiguration. Ich habe bereits versucht, eine Factory für RuntimeBeans zu erstellen:
%Vor%erwartet, dass @Bean im so genannten "Lite" -Modus arbeitet. Ссылка Leider habe ich keinen Unterschied mit gefunden einfach neue RuntimeBean (); Hier ist ein Post mit einem ähnlichen Problem: Wie bekomme ich Bohnen? von FactoryBean Frühling verwaltet?
Es gibt auch Ссылка aber in meinem Fall sieht es wie ein Hammer aus.
Ich habe auch ApplicationContext.getBean ("runtimeBean", args) ausprobiert, wo runtimeBean einen "Prototyp" scope hat, aber getBean ist eine schreckliche Lösung.
Upd1. Um konkreter zu werden, versuche ich diese Klasse umzuformen: Ссылка @see #load () -Methode und finde "return create (cd, false);"
Upd2. Ich fand eine ziemlich interessante Sache namens "Lookup Method Injection" in der Frühjahrsdokumentation: Ссылка
Und auch ein interessantes Jira-Ticket Ссылка wo Phil Webb sagt Ссылка dass javax.inject.Provider sollte hier verwendet werden (es erinnert mich Guice).
Upd3. Es gibt auch Ссылка
Upd4. Das Problem mit all diesen "Lookup" -Methoden ist, dass sie das Übergeben von Argumenten nicht unterstützen. Ich muss auch Argumente übergeben, wie ich es mit applicationContext.getBean ("runtimeBean", arg1, arg2) machen würde. Sieht so aus, als wäre es irgendwann mit Ссылка
behoben wordenUpd5. Google Guice hat eine nette Funktion namens AssistedInject. Ссылка
Sieht so aus, als hätte ich eine Lösung gefunden. Da ich java-basierte Konfiguration verwende, ist es sogar einfacher als du dir vorstellen kannst. Ein alternativer Weg in xml wäre die lookup-Methode, allerdings nur ab der Spring Version 4.1.X, da es die Übergabe von Argumenten an die Methode unterstützt.
Hier ist ein vollständiges Arbeitsbeispiel:
%Vor%Das ist es.
Danke allen.
Ich denke, dass Ihr Konzept falsch ist, indem Sie
RuntimeBean beanRuntime = createRuntimeBean();
verwenden
Sie umgehen den Spring-Container und greifen auf den regulären Java-Konstruktor zurück, daher werden alle Anmerkungen zur Factory-Methode ignoriert und diese Bean wird nie von Spring
hier ist die Lösung, mehrere Prototyp-Beans in einer Methode zu erstellen, nicht hübsch aussehen, aber sollte funktionieren, ich autowired Container in RuntimeBean als Nachweis der Autowiring im Protokoll angezeigt auch können Sie im Protokoll sehen, dass jede Bean ist neue Instanz von Prototyp wenn du führst das aus.
'
%Vor% Sie benötigen nicht Container
, weil alle Laufzeitobjekte von ApplicationContext
erstellt, verwaltet und verwaltet werden sollen. Denken Sie an eine Web-Anwendung, sie sind in etwa gleich. Jede Anfrage enthält wie bereits erwähnt externe Daten / Umgebungsinformationen . Was Sie brauchen, ist ein Prototyp / Request Scoped Bean wie ExternalData
oder EnvironmentInfo
, der Laufzeitdaten über eine statische Art lesen und speichern kann, sagen wir eine statische Factory-Methode.
Wenn Sie einen Container zum Speichern der Laufzeitobjekte benötigen, sollte der Code
lauten %Vor%Offizielles Dokument Singleton-Beans mit Prototyp-Beans-Abhängigkeiten .
Tags und Links java spring dependency-injection refactoring guice