2010-09-28 5 views
94

Lassen Sie uns sagen, dass wir eine Klasse:Wie können Abhängigkeiten im Frühjahr in ein selbstinstanziertes Objekt injiziert werden?

public class MyClass { 
    @Autowired private AnotherBean anotherBean; 
} 

Dann haben wir ein Objekt dieser Klasse (oder einen anderen Rahmen für die Instanz dieser Klasse erstellt haben).

MyClass obj = new MyClass(); 

Ist es möglich, noch die Abhängigkeiten zu injizieren? Etwas wie:

applicationContext.injectDependencies(obj); 

(Ich denke, Google Guice so etwas wie dieses hat)

Antwort

141

Sie können dies unter Verwendung der autowireBean()-Methode von AutowireCapableBeanFactory tun. Sie übergeben ihm ein beliebiges Objekt, und Spring behandelt es wie etwas, das es selbst erstellt hat, und wendet die verschiedenen Autowiring-Teile an.

zu halten, die AutowireCapableBeanFactory zu erhalten, autowire nur das:

private @Autowired AutowireCapableBeanFactory beanFactory; 

public void doStuff() { 
    MyBean obj = new MyBean(); 
    beanFactory.autowireBean(obj); 
    // obj will now have its dependencies autowired. 
} 
+0

Gute Antwort (+1). Es gibt auch eine zweite Methode, mit der Sie Einfluss darauf nehmen können, wie das Autodiring passiert: http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/beans/factory/config/AutowireCapableBeanFactory.html# autowireBeanProperties% 28java.lang.Object,% 20int,% 20boolean% 29 –

+0

Aber was ist, wenn ich zwei Objekte habe und zuerst autowires zweite. Wie beschäftigt sich die Autowire Bean Factory mit Abhängigkeiten in diesem Fall? –

+2

Das ist eigentlich ein schlechtes Muster. Wenn Sie MyBean wirklich so verwenden, haben Sie einfach Konstruktor mit AnotherBean als Parameter. Etwas wie: 'code' private @Autowired AnotherBean Bean; public void doStuff() {MyBean obj = neuer MyBean (Bean); } 'Code'. Scheint so zu sein wie bei all diesen Anmerkungen, die Leute werden wirklich verwirrt und benutzen einfach nicht das Grundmuster, das in Java SDK seit Tag 1 war :( – Denis

-6

Nicht ohne einige Abhilfen, wie Frühling nichts über diese Instanz kennt.

Die eigentliche Frage ist: Warum erstellen Sie Instanzen einer Klasse, in die Abhängigkeiten manuell eingefügt werden sollen, anstatt Spring von ihnen steuern zu lassen? Warum wird die Klasse MyClassMyClass injiziert?

+12

Ihre Antwort falsch ist, und Ihre „wirkliche Frage“ ist ein Kommentar, keine Antwort. –

13

Sie auch Ihre MyClass mit @Configurable Anmerkung markieren:

@Configurable 
public class MyClass { 
    @Autowired private AnotherClass instance 
} 

Dann es Erstellungszeit wird seine Abhängigkeiten automatisch injizieren . Sie sollten auch <context:spring-configured/> in Ihrem Anwendungskontext XML haben.

+2

Galz666, Ihre Methode sieht viel sauberer für das, was ich tun möchte. Aber ich kann es nicht zur Arbeit bringen. Ich habe keine XML-Datei und verwende vollständig Java-Konfiguration. Gibt es ein Äquivalent zu ''? – masstroy

+0

siehe http://stackoverflow.com/a/4703781/404615 –

+0

Dies ist eine saubere Lösung, erfordert aber ein wenig mehr Aufwand: Sie sollten entweder laden-Zeit Weben als iimuhin zeigt oben oder fügen AspectJ Compiler zu Projekt. Ladezeit, wie der Name vermuten lässt, verursacht zusätzliche Kosten zur Laufzeit. – jsosnowski

0

Gerade die gleiche Notwendigkeit und in meinem Fall war es bereits die Logik in nicht Spring verwaltbare Java-Klasse, die Zugriff auf ApplicationContext hatte. Inspiriert von Scaffman. Gelöst von:

AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory(); 
factory.autowireBean(manuallyCreatedInstance); 
Verwandte Themen