Angenommen, Sie haben eine Prototyp-Bean-Klasse wie folgt:
%Vor% Also, ist es möglich, @Autowired
zu verwenden, um eine solche Bean in einer anderen Klasse zu verdrahten, die den nicht standardmäßigen Konstruktor Foobar(String foo)
verwenden sollte, um die Bean zu instanziieren?
update
Im obigen Beispiel ist der Konstruktorparameter String foo
nicht aus dem Anwendungskontext verfügbar, sondern dynamisch. Den Konstruktor mit @Autowired
annotieren zu lassen und dann foo
irgendwo im Kontext anzugeben, scheint hier keine ideale Lösung zu sein.
Hier sind 3 Möglichkeiten, es zu tun, schau dir einfach die beste für deinen Fall an:
Besser, wenn : Sie haben alles, was Sie zum Erstellen Ihrer Prototyp-Bean im Kontext benötigen (selbst für Eigenschaften wie @Value("${prop}")
)
Wenn Sie eine automatische Methode benötigen, müssen Sie alles haben, was benötigt wird, um die Bean im Kontext zu instanziieren (sogar für eine Prototyp-Bean). Falls Sie alles in Ihrem Kontext benötigen, können Sie den Konstruktor einfach mit @Autowired
annotieren und Spring erledigt den Rest für Ihren.
FactoryBeans
Besser wenn : Wenn Sie einen XML-basierten Kontext verwenden, werden Sie dies bevorzugen.
Eine andere Möglichkeit, wenn Sie eine personalisierte Methode benötigen, wäre FactoryBean
s. Aus der Dokumentation :
Schnittstelle, die von Objekten implementiert werden soll, die in einer BeanFactory verwendet werden und selbst Factories sind. Wenn ein Bean diese Schnittstelle implementiert, wird es als Factory für ein Objekt verwendet, das nicht direkt als eine Bean-Instanz angezeigt werden soll, die selbst verfügbar gemacht wird.
Das FactoryBean
wird von Spring nur zum Erstellen des Objekts verwendet, das Sie angefordert haben (als Prototyp oder Singleton).
Für Ihren Fall könnten Sie eine Implementierung wie folgt haben:
%Vor% Und Sie könnten einfach @Autowired
FooBar
für andere Instanzen Ihres Kontextes verwenden.
@Configuration
Besser wenn : Wenn Sie Ihren Kontext bereits mithilfe von Anmerkungen konfiguriert haben, werden Sie diesen Weg definitiv bevorzugen.
Eine dritte Möglichkeit, dies zu tun, und das ist mein Favorit, würde Ihre @Configuration
-Klasse verwenden. Aus der Dokumentation :
public @interface Configuration
: Gibt an, dass eine Klasse mindestens eine @Bean-Methode deklariert vom Spring-Container verarbeitet, um Bean-Definitionen zu generieren und Serviceanforderungen für diese Beans zur Laufzeit, zum Beispiel:
Innerhalb dieser Klasse könnte eine Methode wie folgt aussehen:
%Vor%Sie müssen Ihren Konstruktor mit @Autowired kommentieren und für den Parameter, der an den Konstruktor übergeben werden muss, wenn dein Bean instanziiert wird, musst du einen nicht-primitiven Typparameter verwenden:
Zum Beispiel:
%Vor%und dann kommentieren Sie Ihre DataSource mit:
%Vor%Da die Komponentensuche aktiviert wurde, versucht Spring eine andere Foobar-Bean automatisch zu erkennen und zu registrieren. Dies wird jedoch fehlschlagen, da spring kein Objekt mithilfe des definierten Konstruktors erstellen kann, da Sie den Konstruktor / die Parameter im Konstruktor nicht automatisch verdrahtet haben. Als zweiten Schritt wird Spring versuchen, eine Foobar mit einem Konstruktor ohne Argumente zu erstellen. Daher müssen Sie den Konstruktor, den Sie in der Datei spring-config definiert haben, automatisch verdrahten, um diesen Fehler zu beheben. Weitere Informationen zu diesem Thema finden Sie in diesem Artikel .