2012-10-16 10 views
25

zu verwenden Ich lese das Buch Pro Spring 3. Es hat einen gewissen Absatz, der mich wirklich verwirrt hat. Der Absatz beschäftigt sich mit dem Autofahren im Frühjahr. Hier ein Auszug:Wann Autowiring in Frühling

In den meisten Fällen ist die Antwort auf die Frage, ob Sie autowiring verwenden sollten, ist auf jeden Fall „nein!“ Autowiring Sie Zeit in kleinen Anwendungen speichern kann, aber in vielen Fällen führt zu schlechten Praktiken und ist in großen Anwendungen unflexibel. Die Verwendung von byName scheint wie eine gute Idee, aber es kann dazu führen, dass Sie Ihre Klassen künstliche Eigenschaft Namen geben, so dass Sie die Autowiring-Funktionalität nutzen können. Die ganze Idee hinter Frühling ist, dass Sie Ihre Klassen erstellen können, wie Sie mögen und haben Frühling für Sie arbeiten, nicht umgekehrt ...

... Für jede nicht-triviale Anwendung steuern bei allen autowiring klar Kosten.

Ich habe immer das @ Autowired-Tag in Anwendungen verwendet, die ich erstellt habe. Kann jemand erklären, was damit nicht stimmt und was ich stattdessen verwenden soll?

Ein Mini-Beispiel dafür, wie ich die meisten Dinge jetzt handhaben ist:

@Service("snippetService") 
public class SnippetService { 

    @Autowired 
    private TestService testService; 

    public Snippet getSnippet() { 
     return testService.getSnippet(); 
    } 
}  

Ist autowiring wie diese „falschen“ mit oder bin ich etwas fehlt?

+0

Ich bin kein Spring-Benutzer, aber ich kenne Guice und CDI. Diese Frameworks machen im Wesentlichen nichts anderes als autowiring; Für jede annotierte Injektionsstelle wird das Framework gehen und etwas finden, das es injizieren kann, basierend auf dem Typ und allen vorhandenen Qualifiern, und dann injizieren. Die Leute haben wirklich ziemlich große Anwendungen mit diesem Ansatz gebaut; Ich arbeite an einem. Ich glaube nicht, dass sie auf die Probleme gestoßen sind, die von den Spring-Autowire-Phobes prophezeit wurden. –

+0

Ein Vorbehalt allerdings: Diese Frameworks führen kein Autowiring im Sinne von 'autowire = 'byType" 'durch. Wenn, wie @mrembisz sagt, der Artikel speziell davor warnt, dann sind die Erfahrungen von Guice und CDI nicht relevant. –

Antwort

23

Ich glaube, dass hier zwei Dinge verwirrt sind. Was mit "Autowiring" in diesem Kapitel gemeint ist, bezeichnet Bean zur automatischen Erkennung und Injektion von Abhängigkeiten. Dies kann durch die Einstellung des "bow-Attributs" "autowire" erreicht werden.

Dies ist in der Tat im Gegensatz zu @Autowired, wo Sie Feld oder Setter explizit für Abhängigkeitsinjektion angeben.

Schauen Sie hier: http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/beans.html#beans-factory-autowire.

es zu erklären, übernehmen Sie

public class SnippetService { 

    private TestService testService; 

    public Snippet getSnippet() { 
     return testService.getSnippet(); 
    } 

    public void setTestService(TestService testService) { 
     this.testService = testService; 
    } 
} 

haben Wenn Sie eine Bohne definiert:

<bean class="mypackage.SnippetService" autowire="byType"/> 

Frühling Bohne von passendem Typ, in diesem Fall TestService zu injizieren würde versuchen, durch setTestService Setter Aufruf .Auch wenn Sie @Autowired nicht verwendet haben. Dies ist in der Tat gefährlich, da einige Setter möglicherweise nicht im Frühjahr benannt werden sollen.

Wenn Sie autowire = "no" einstellen, wird nichts injiziert, es sei denn, dies ist mit @Autowired, @Resource, @Inject gekennzeichnet.

+1

Das macht mehr Sinn. Ich hatte diese Situation gerade heraufkommen. Ich wollte Werte aus einer Eigenschaftendatei lesen und sie in eine Bean einfügen. Nur so konnte ich beim Start meiner App herausfinden, wie ich die Bean in XML verdrahte (und die Eigenschaften injiziere). Am Ende benutzte ich das "byName" -Attribut (weil die Bean auch als @Component markiert war). und dann @Autowired @Qualifier ("nameIChose") verwendet, wenn die Bean in eine andere Klasse injiziert wird. Es ist die einzige Bean, die ich geschrieben habe, die ich mit XML verdrahte. – Marvo

+0

Vielen Dank für die Klärung! – geoffreydv

+0

Ich habe Autowiring nützlich in Fällen gefunden, in denen ich eine Factory-Bean hatte, die eine andere Bean erstellt (deren Name der Implementierungsklasse in einer Systemeigenschaft beschrieben wurde, sodass ich die gesamte Verdrahtung in XML nicht definieren konnte). Normalerweise ziehe ich es vor, meine Verdrahtung explizit zu machen; Es vereinfacht die langfristige Wartung erheblich, wenn die Dinge explizit sind. –

3

Es ist nichts falsch mit dem, was Sie haben, vor allem, wenn Sie mit einer Implementierung von TestService sowieso beginnen. Wie Johan jedoch erwähnt, ist es besser, @javax.annotation.Resource zu verwenden, was Ihnen auch erlaubt, spezifischer zu sein, wenn Sie das brauchen (zum Beispiel mit dem Attribut name oder type).

+2

Die Verwendung von '@ Qualifier' wird zugunsten von '@ Resource' abgeraten. –

+0

Das ist richtig, danke, dass Sie darauf hingewiesen haben. –

+0

Seit Spring IoC Container JSR 250 implementiert, macht dies einen Fall, @Resource die ganze Zeit im Gegensatz zu @Autowired zu verwenden? Edit: anscheinend kommt es darauf an (Überraschung!) Interessanter Forenbeitrag http://forum.springsource.org/showthread.php?48563-Autowired-and-Resource-difference – dardo

2

Das einzige Problem, das ich hier sehe, ist, dass Sie ein wenig die Kontrolle verlieren. Angenommen, Sie haben zwei oder mehr Instanzen von TestService in Ihrer App-Konfiguration und Sie möchten eine davon verwenden. Autowire zu haben ist kniffliger als die Verwendung von config XML, um für Sie zu injizieren. Dies ist, was Ihr Buch versucht zu zeigen, d. H. Es wird schwierig/schwieriger in großen Anwendungen, wo solche Bedürfnisse häufiger sind.

Wenn Sie solche Situationen nicht haben, denke ich, es ist in Ordnung.

+1

Aber was Sie in dieser Situation tun, ist die Annotation @Qualifier, um anzugeben, welche dieser Beans Sie wollen. – Marvo

+0

Ich habe nicht gesagt, dass Sie das nicht tun können. Alles was ich meinte, ist folgendes: Konfigurationsdateien sollten die Abhängigkeiten extern einspeisen und verwenden. Indem wir Annotationen verwenden, bringen wir das in die Implementierungsklasse selbst. Dies wird in größeren Anwendungen schwieriger/schwieriger. –

+1

Ich denke das ist subjektiv. Ich finde es nicht viel schwieriger, große sperrige XML-Dateien zu verwalten. Und wenn eine neue Implementierung für eine bestimmte Schnittstelle erforderlich ist, müsste ich das XML und die Klasse ändern. mit autowiring würde ich einfach die klasse ersetzen. Eine weniger Änderung, eine weniger mögliche Fehler. – Marvo

0

Autowire über XML ist absolut sicher und hilfreich, wenn Sie auf Konstruktor basierenden Autowiring tun, besonders wenn Sie die Kollaborateure zum privaten Finale machen.

Ich bin nett schockiert der Autor sagte, dass wenn ich das oben auf einem extrem großen Frühling 2.5 Projekt vor ein paar Jahren gemacht habe. (zu der Zeit, als die Annotation-Unterstützung in JBoss nicht funktionierte)

Verwandte Themen