Spring @ Autowired Nutzung verstehen

Ich lese die Spring 3.0.x Referenzdokumentation, um Spring Autowired Annotation zu verstehen:

3.9.2 @Autowired und @Inject

Ich kann die folgenden Beispiele nicht verstehen. Müssen wir etwas im XML tun, damit es funktioniert?

BEISPIEL 1

public class SimpleMovieLister { private MovieFinder movieFinder; @Autowired public void setMovieFinder(MovieFinder movieFinder) { this.movieFinder = movieFinder; } // ... } 

Beispiel 2

 public class MovieRecommender { private MovieCatalog movieCatalog; private CustomerPreferenceDao customerPreferenceDao; @Autowired public void prepare(MovieCatalog movieCatalog, CustomerPreferenceDao customerPreferenceDao) { this.movieCatalog = movieCatalog; this.customerPreferenceDao = customerPreferenceDao; } // ... } 

Wie können die zwei classn autowired werden, die dieselbe Schnittstelle implementieren und dieselbe class verwenden?

Beispiel:

 class Red implements Color class Blue implements Color class myMainClass{ @Autowired private Color color; draw(){ color.design(); } } 

Welche Designmethode wird aufgerufen? Wie stelle ich sicher, dass die Designmethode der Red-class aufgerufen wird und nicht Blue?

   

    Mit der @Autowired Annotation können Sie Konfigurationen an anderen @Autowired überspringen und einfach für Sie @Autowired . Angenommen, Ihr Paket ist com.mycompany.movies , müssen Sie dieses Tag in Ihre XML (Anwendungskontextdatei) com.mycompany.movies :

      

    Dieses Tag wird automatisch gescannt. Angenommen, jede class, die eine Bean werden soll, wird mit einer korrekten Annotation wie @Component (für einfache Bean) oder @Controller (für ein Servlet-Steuerelement) oder @Repository (für DAO classn) versehen und diese classn befinden sich irgendwo unter dem Paket com.mycompany.movies , Spring wird alle von diesen finden und eine Bean für jede erstellen. Dies geschieht in 2 Scans der classn – das erste Mal, wenn es nur nach classn sucht, die eine Bean werden müssen, und die erforderlichen Injektionen mapped, und beim zweiten Scan injiziert es die Beans. Natürlich können Sie Ihre Beans in der traditionelleren XML-Datei oder mit einer @Configuration- class (oder einer beliebigen Kombination der drei) definieren.

    Die Annotation @Autowired teilt Spring mit, wo eine Injektion erfolgen muss. Wenn Sie es in eine Methode setMovieFinder , versteht es (durch den @Autowired + die @Autowired Annotation), dass eine Bean injiziert werden muss. In der zweiten Suche sucht Spring nach einer Bean vom Typ MovieFinder , und wenn sie eine solche Bean findet, wird sie in diese Methode injiziert. Wenn zwei solche Bohnen gefunden werden, erhalten Sie eine Exception . Um die Exception zu vermeiden, können Sie die Annotation @Qualifier und ihr mitteilen, welche der beiden Beans auf folgende Weise injiziert wird:

     @Qualifier("redBean") class Red implements Color { // Class code here } @Qualifier("blueBean") class Blue implements Color { // Class code here } 

    Oder wenn Sie die Beans lieber in Ihrem XML deklarieren möchten, sieht das etwa so aus:

       

    In der @Autowired Deklaration müssen Sie außerdem den @Qualifier hinzufügen, um @Qualifier , welche der beiden @Qualifier injiziert werden soll:

     @Autowired @Qualifier("redBean") public void setColor(Color color) { this.color = color; } 

    Wenn Sie nicht zwei Annotationen ( @Autowired und @Qualifier ) verwenden @Resource , können Sie @Resource , um diese beiden zu kombinieren:

     @Resource(name="redBean") public void setColor(Color color) { this.color = color; } 

    Die @Resource (Sie können einige zusätzliche Daten darüber im ersten Kommentar zu dieser Antwort lesen) erspart Ihnen die Verwendung von zwei Anmerkungen und stattdessen verwenden Sie nur eine.

    Ich füge nur zwei weitere Kommentare hinzu:

    1. Eine gute Vorgehensweise wäre, @Inject anstelle von @Autowired da es nicht Spring-spezifisch ist und Teil des JSR-330 Standards ist .
    2. Eine weitere gute Methode wäre, @Inject / @Autowired anstelle einer Methode auf einen Konstruktor zu setzen. Wenn Sie es in einen Konstruktor NullPointerException Sie NullPointerException dass die injizierten Beans nicht null sind und schnell fehlschlagen, wenn Sie versuchen, die Anwendung zu starten und eine NullPointerException vermeiden, wenn Sie die Bean tatsächlich verwenden müssen.

    Also, um es zusammenzufassen: Die @Autowired Annotation erspart Ihnen die Notwendigkeit, die Verdrahtung selbst in der XML-Datei (oder auf andere Weise) zu tun und findet nur für Sie, was wo injiziert werden muss, und tut das für Sie.

    Update : Um das Bild zu vervollständigen, habe ich eine neue Frage zur @Configuration class erstellt.

    Nichts in dem Beispiel sagt, dass die “classn die gleiche Schnittstelle implementieren”. MovieCatalog ist ein Typ und CustomerPreferenceDao ist ein anderer Typ. Der Frühling kann sie leicht voneinander unterscheiden.

    Im Spring 2.x erfolgte die Verkabelung von Beans hauptsächlich über Bean-IDs oder Namen. Dies wird immer noch von Spring 3.x unterstützt, aber oft haben Sie eine Instanz einer Bean mit einem bestimmten Typ – die meisten Dienste sind Singletons. Namen für diese zu erstellen ist mühsam. So begann Spring “autowire by type” zu unterstützen.

    Was die Beispiele zeigen, sind verschiedene Möglichkeiten, mit denen Sie Beans in Felder, Methoden und Konstruktoren einspeisen können.

    Das XML enthält bereits alle Informationen, die Spring benötigt, da Sie den vollständig qualifizierten classnnamen in jeder Bean angeben müssen. Sie müssen jedoch ein wenig vorsichtig mit Schnittstellen sein:

    Dieses Autowiren schlägt fehl:

      @Autowired public void prepare( Interface1 bean1, Interface1 bean2 ) { ... } 

    Da Java die Parameternamen nicht im Byte-Code speichert, kann Spring nicht mehr zwischen den beiden Beans unterscheiden. Das @Qualifier besteht darin, @Qualifier zu verwenden:

      @Autowired public void prepare( @Qualifier("bean1") Interface1 bean1, @Qualifier("bean2") Interface1 bean2 ) { ... } 

    Ja, Sie können die XML-Datei des Spring-Servlet-Kontextes konfigurieren, um Ihre Beans (dh classn) zu definieren, damit sie die automatische Injektion für Sie durchführen können. Beachten Sie jedoch, dass Sie andere Konfigurationen durchführen müssen, um Spring zu starten und zu starten. Dies ist am besten, wenn Sie einem grundlegenden Tutorial folgen.

    Sobald Sie Ihre Spring wahrscheinlich konfiguriert haben, können Sie Folgendes in Ihrer Spring-Servlet-Kontext-XML-Datei für Beispiel 1 tun, um zu funktionieren ( ersetzen Sie den Paketnamen von com.movies durch den tatsächlichen Paketnamen und wenn es sich um einen Drittanbieter handelt) class, dann stellen Sie sicher, dass sich die entsprechende JAR-Datei im classnpfad befindet):

      

    oder wenn die MovieFinder-class einen Konstruktor mit einem primitiven Wert hat, könnten Sie so etwas

        

    oder wenn die MovieFinder-class einen Konstruktor hat, der eine andere class erwartet, könnten Sie so etwas tun,

        

    … wo ‘ otherBeanRef ‘ eine andere Bean ist, die eine Referenz auf die erwartete class hat.

    @Autowired

    Lassen Sie Spring mithilfe der @Autowired-Annotation andere Beans in Ihre classn einbinden.

     @Service public class CompanyServiceImpl implements CompanyService { @Autowired private CompanyDAO companyDAO; ... } 

    Spring Annotation Tip Spring-Bohnen können nach Name oder nach Typ verdrahtet werden. @Autowire ist standardmäßig eine typgesteuerte Injektion. @Qualifier Spring Annotation kann zur weiteren Feinabstimmung des Autowiderstands verwendet werden. @Resource (javax.annotation.Resource) Annotation kann für die Verdrahtung nach Namen verwendet werden. Bohnen, die selbst als Sammlungs- oder Kartentypen definiert sind, können nicht über @Autowired injiziert werden, da die Typübereinstimmung nicht ordnungsgemäß auf sie angewendet werden kann. Verwenden Sie @Resource für solche Beans, indem Sie sich auf die spezifische Sammlung oder Map-Bean anhand des eindeutigen Namens beziehen