Wie der Name schon sagt, besteht die Annotationsinjektion darin, die Injektion durch Anmerkungen zu realisieren. Häufige Anmerkungen im Zusammenhang mit Frühjahr und Injektion umfassen Autoweg, Ressourcen, Qualifikationsmittel, Service, Controller, Repository und Komponente.
Autoweged ist eine automatische Injektion, findet automatisch die entsprechende Bohne aus dem Kontext der Feder zu Injektion
Ressource wird verwendet, um die Namensinjektion anzugeben
Qualifikation und Autoweg arbeiten zusammen, um den Namen der Bohne anzugeben
Service, Controller und Repository markieren die Klasse als Service -Layer -Klasse, Controller Layer -Klasse und Datenspeicherschichtklasse. Bei der Konfiguration der Spring -Scan -Annotation werden diese Klassen so markiert, dass sie Bohnen erzeugen.
Komponente ist ein allgemeiner Begriff. Markierungskurse sind Komponenten. Bei der Konfiguration von Frühlingscans und Anmerkungen werden diese Klassen so markiert, dass sie Bohnen erzeugen.
Frühling unterstützt mehrere Annotationsmethoden für die Abhängigkeitsinjektion von Bohnen:
@Resource javax.Annotation JSR250 (gemeinsame Annotationen für Java) @inject javax.inject JSR330 (Abhängigkeitsinjektion für Java) @autowired org.springframework.bean.Factory Spring Spring
Intuitiv ist @autowired eine Annotation, die im Frühjahr bereitgestellt wird, und die anderen sind eingebaute Annotationen von JDK selbst, und der Frühling unterstützt auch diese Anmerkungen. Aber was ist der Unterschied zwischen diesen drei, wenn sie verwendet werden? Nach dem Testen der Methode fand der Autor einige interessante Merkmale.
Der Unterschied wird wie folgt zusammengefasst:
1. @autowired hat eine erforderliche Eigenschaft, die als falsch konfiguriert werden kann. In diesem Fall wird eine Ausnahme nicht ausgelöst, wenn die entsprechende Bohne nicht gefunden wird. @Inject und @Resource liefern keine entsprechenden Konfigurationen, sodass Sie sie finden müssen, da sonst eine Ausnahme ausgelöst wird.
2. @Autowired und @Inject sind im Grunde genommen gleich, da beide AutoWiredAnnotationBeanPostProcessor verwenden, um die Abhängigkeitsinjektion zu behandeln. @Resource ist jedoch eine Ausnahme, die CommonannotationBeanPostProcessor verwendet, um die Abhängigkeitsinjektion zu bewältigen. Natürlich sind beide BeanPostProcessors.
@Autowired und @Inject - Standard automatisch nach Typ - automatisch durch den Qualifikationsnamen kann explizit über @Qualifier angegeben werden. . Aber zu diesem Zeitpunkt, wenn der per Feldnamen fehlgeschlagene AutoWired fehlschlägt, degeneriert er nicht mehr nach Typ.
Tipps qualifizierter Name vs Bean Name
Im Frühjahrsdesign entspricht der qualifizierte Name nicht dem Bean -Namen, letzteres muss eindeutig sein, aber der erstere ähnelt der Funktion eines Tags oder einer Gruppe, wobei bestimmte Bohnen klassifiziert werden. Es kann den Effekt von GetByTag (Gruppe) erreichen. Für XML-konfigurierte Bohnen können Sie den Bean-Namen über das ID-Attribut angeben (falls nicht angegeben, der Klassenname ist standardmäßig Kleinbuchstaben) und der Qualifikationsname wird über das Tag angegeben:
<bean id = "lamborghini"> <qualifier value = "luxury"/> <!-Injizieren Sie alle Abhängigkeiten, die von dieser Bean gefordert werden-> </bean>
Wenn es durch Annotation der Fall ist, können Sie den Qualifikationsnamen über die @Qualifier -Annotation angeben und den Bean -Namen über den Wert von @Named oder @Component (@Service, @Repository usw.) angeben:
@Component ("Lamborghini") @Qualifier ("Luxus") öffentliche Klasse Lamborghini implementiert Car {}oder
@Component @Named ("Lamborghini") @Qualifier ("Luxus") öffentliche Klasse Lamborghini implementiert Car {}Wenn der Bean -Name nicht angegeben ist, wird der Frühling im Klassennamen standardmäßig in Kleinbuchstaben (Lamborghini => Lamborghini) standardmäßig dargestellt.
3. Verwenden Sie die Anotations -Injektionsabhängigkeitsmethode, um vor der XML -Injektionsmethode durchzuführen. Wenn aus der Abhängigkeit von derselben Bean zwei Einspritzverfahren gleichzeitig angewendet werden, wird XML bevorzugt. Ich bin jedoch nicht besorgt, dass die durch Anotation injizierten Abhängigkeiten keine in XML konfigurierten Bohnen injizieren können. Die Abhängigkeitsinjektion erfolgt nach der Registrierung der Bean.
4. Die aktuelle automatische Autodität (der Autor verwendet die Version 3.2.3.Release), die Implementierung von Spring AutowiredAntationBeanPostProcessor enthält "Fehler", was bedeutet, dass @Autowired und @Inject Fallstricke (als Gruben genannt, nicht Fehler, weil sie vorsätzlich zu sein scheinen ...). Dies ist ein Fehler, der von online stammt und auch der Grund für das Schreiben von Artikeln hier ist. Die Szene lautet wie folgt:
Es gibt die folgenden Definitionen in Anwendungskontext.xml:
<xml Version = "1.0" coding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://ww.ww.org/2001/xmlschema-instance" " xmlns: aop = "http://www.springframework.org/schema/aop" xmlns: context = "http://www.spingframework.org/schema/context" xmlns: utring XSI: Schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/scha. http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springFramework.org/schema/util http://www.springframe.org/sschema/util/util/Schema/Schema/Schema/Schema/SCHEMA <Kontext: Annotation-Konfiguration /> <Kontext: Komponent-scan-Basis-Package = "me.arganzheng.study" /> <util: konstant id = "en" static-field = "me.arganzheng.study.spring.autowired.constants.language.en" /> <util: konstant id = "ja" ja "ja:" ja "ja" ja "ja" ja "ja" ja "ja" ja "ja: static-field = "me.arganzheng.study.spring.autowired.constants.uanganguage.jp" /> <util: konstant id = "ind" static-field = "me.arganzheng.study.spring.autowired.constants.language.ind" /> <uth. static-field = "me.arganzheng.study.spring.autowired.constants.language.pt" /> <util: konstant id = "th" static-field = "me.arganzheng.study.spring.autowired.constants.language.th" /> <util: constant id = "ar" ar "ar" ar "ar" ar "ar ar" ar ar "ar ar" ar ar "ar are" ar are "ar ARUtowired.constants static-field="me.arganzheng.study.spring.autowired.Constants.Language.AR" /> <util:constant id="en-rIn" static-field="me.arganzheng.study.spring.autowired.Constants.Language.EN_RIN" /> <util:map id="languageChangesMap" key-type = "java.lang.String" value-type = "java.lang.String"> <Eintragstastatur = "pt" value = "pt" /> <Eintrags-Key = "BR" value = "pt" /> <Eintrags Key = "jp" JA ". key = "id" value = "ind" /> <Eintragsetastatur = "en-rin" value = "en-rin" /> <Eintragsetaste "in" value = "en-rin" /> <Eintragstaste = "en" value = "en" /> <Eintragsschlüssel = "gb" value = "En" /> <Eintragstaste "th" -Strieb ". </util: map> </beans>
Die vom statischen Feld angewendeten Konstanten sind in der folgenden Klasse definiert:
Paket me.arganzheng.study.spring.autowired; public interface Constants {öffentliche Schnittstelle Sprache {public static Final String en = "CommonConstants.lang_english"; public static final String jp = "CommonConstants.lang_japanese"; public static final String ind = "CommonConstants.lang_indonesian"; public static final String pt = "CommonConstants.lang_Portuguese"; public static final String th = "CommonConstants.lang_Thai"; public static final String en_rin = "CommonConstants.lang_english_india"; public static final String ar = "CommonConstants.lang_arabic"; }}Wenn wir dann die Abhängigkeit im Code wie folgt deklarieren:
public class AutoWiredTest erweitert BaseSpringtestCase {@autowired Private Map <String, String> Languagechangesmap; @Test public void testAutowired () {Notnull (Languagechangesmap); System.out.println (LanguageChangesmap.getClass (). GetImlenname ()); System.out.println (Languagechangesmap); }}Ratet mal was, etwas Seltsames passiert!
Die Betriebsergebnisse sind wie folgt:
LinkedHasMap {en = CommonConstants.lang_english, Ja = CommonConstants.lang_japanese, ind = CommonConstants.lang_indonesian, pt = CommonConstants.Lang_portuguese, th = Commonconstants.lang_Thai, arn = Commonconstants.lang_arabic, en-rin = Commonconstants.Lang_indants.Das heißt, Karte
Ernst: AUSGABE AUSGABE UND TESTExecutionListener zuzulassen
[org.springframework.test.context.support.DependencyInjectionTestexecutionListener@5c51ee0a] zur Erstellung von Testinstanzen [me.arganzheng.study.spring.autowired.AutowiredTest@beancraction: MGRAGRAGE MITS -NAYRAMEDFRAME.BEANCACTIONSWAHRS: 'me.arganzheng.study.spring.autowired.autowiredtest': Injektion von automatischen Abhängigkeiten fehlgeschlagen; Eine verschachtelte Ausnahme ist org.springframework.beans.factory.beancreationException: konnte nicht automatisch field: private java.util.map me.arganzheng.study.spring.autowired.autowiredtest.slanguagechangesmap; Eine verschachtelte Ausnahme ist org.springFramework.bean.factory.nosuchbeandeFinitionException: Keine qualifizierende Bean von Typ [java.lang.String] für die Abhängigkeit gefunden [Karte mit Werttyp Java.lang.String]: Erwartet mindestens 1 Bean, die als Autokandidat für diese Abhängigkeit qualifiziert sind. Abhängigkeit Annotationen: {@org.springFramework.bean.factory.annotation.autowired (erforderlich = true)} ... ed von: org.springFramework.bean.factory.nosuchbeandeFinitionException: Keine Qualifikationsbean [java.lang.rang.string] Found. Was als Autowire -Kandidat für diese Abhängigkeit gilt. Abhängigkeitsanmerkungen: {@org.springframework.bean.factory.annotation.autowired (erforderlich = true)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.RenosuchbeandeFinitionException (DefaultListableBeactory.java:986) ATLETTIGE (DefaultListable org.springFramework.beans.factory.support.DefaultListableBeanFactory.DoresoldePendency (DefaultListableBeanFactory.java:843) bei org.springFramework.bean.factory.Support.DefaultableListableBeAnfactory. org.springframework.bean.factory.annotationIch habe es debuggen und stellte fest, dass es im Frühling tatsächlich ein Fehler war. Diese Methode gibt es in StandardlistableBeanFactory mit dieser Methode:
Protected Objected DoresSoldePendency (Abhängigkeitskriptordeskriptor, Klasse <?> Typ, String -Beanname, Set <String> AutoWiredbeAnnames, TypeConverter typeConverter aus. if (keytype == null ||! string.class.issignableFrom (keytype)) {if (Descriptor.isRequired ()) {werfen Sie eine neue FatalbeanException aus ("Key Type [" + keytype + "] von Karte [" + type.getName () + "] muss [java.Lang.Lang.Lang.string]"; } return null; } Class <?> ValuEType = Descriptor.getMapvalUeType (); if (valuEType == null) {if (Descriptor.isRequired ()) {werfen Sie eine neue FatalbeanException aus ("kein Werttyp für MAP [" + type.getName () + "]"); } return null; } Map <String, Object> MatchingBeans = findAutoWirecandidates (Beanname, ValuEType, Deskriptor); if (MatchingBeans.isempty ()) {if (Descriptor.isrequired ()) {RaisenosuchbeandeFinitionException (Valuetype, "MAP With Value type" + ValueType.getName (), Descriptor); } return null; } if (AutoWiredBeannames! } return MatchingBeans; } ...}Der Schlüssel ist dieser Satz: Karte
Ernst: AUSGABE AUSGABE UND TESTExecutionListener zuzulassen
[org.springframework.test.context.support.DependencyInjectionTestexecutionListener@9476189] zur Erstellung von Testinstanzen [me.arganzheng.study.spring.autowired.autowiredtest@2d546e21] ... verursacht durch: org.springframework.beans.factory.nosuchbeandeFinitionException: Keine qualifizierende Bean von Typ [Java.lang.String] für Abhängigkeit gefunden [Karte mit Werttyp Java.lang.String]: Erwartet mindestens 1 Bean, die als AutoWire -Kandidat für diese Abhängigkeit qualifiziert ist. Abhängigkeitsanmerkungen: { @org.springframework.bean.factory.annotation.autowired (fordert = true), @org.springframework.bean.factory.annotation.qualifier (value = languagechangesmap)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raisenosuchbeandeFinitionException (StandardsListableBeanFactory.java:986) at org.springFramework.beans.factory.support.DefaultListableBeanFactory.DoresoldePendency (DefaultListableBeanFactory.java:843) bei org.springFramework.bean.factory.Support.DefaultableListableBeAnfactory. org.springframework.bean.factory.annotationNach dem Debuggen stellte ich fest, dass der Ausführungspfad mit dem nicht angegebenen Qualfie -Namen übereinstimmt. Haben Sie den Bean -Namen nicht angegeben? Warum ist es immer noch nach Typ automatisch? Nach einem genaueren Blick fand ich es heraus. Die DoresSoldePendency -Methode von StandardListableBeanFactory macht zuerst den Unterschied zwischen den Typen:
Protected Objected DoresSoldePendency (DependyChescriptor Deskriptor, Klasse <?> Typ, String -Beanname, Set <String> AutoWiredbeAnnames, TypeConverter typeConverter) löscht BeanSexception {Object value = getautoWirecandIdateresolver (). if (value! BeanDefinition bd = (Beanname! = NULL && enthältBean (Beanname)? value = evaluateBeANDefinitionString (Strval, BD); } TypeConverter Converter = (TypeConverter! = NULL? TypeConverter: GetTypeConverter ()); return (Descriptor.getfield ()! } if (type.isArray ()) {class <?> componentType = type.getComponentType (); Karte <String, Object> MatchingBeans = findAutoWirecandidates (Beanname, componentType, Deskriptor); if (MatchingBeans.isempty ()) {if (Descriptor.isrequired ()) {RaisenosuchbeandeFinitionException (componentType, "Array of" + componentType.getName (), Descriptor); } return null; } if (AutoWiredBeannames! } TypeConverter Converter = (TypeConverter! = NULL? TypeConverter: GetTypeConverter ()); return converter.convertifNeory (MatchingBeans.values (), Typ); } else if (collection.class.IssidesignableFrom (type) && type.Isersinterface ()) {class <?> elementtype = Descriptor.getCollectionType (); if (elementtype == null) {if (Descriptor.isRequired ()) {neue FatalbeanException werfen ("kein Elementtyp für die Sammlung [" + type.getName () + "]"); } return null; } Map <String, Object> MatchingBeans = findAutoWirecandidates (Beanname, elementtype, Deskriptor); if (matchingBeans.isempty ()) {if (Descriptor.isrequired ()) {RaisenosuchbeandeFinitionException (elementtype, "Sammlung von" + elementtype.getName (), Descriptor); } return null; } if (AutoWiredBeannames! } TypeConverter Converter = (TypeConverter! = NULL? TypeConverter: GetTypeConverter ()); return converter.convertifNeory (MatchingBeans.values (), Typ); } else if (map.class.IssidesignableFrom (type) && type.Isersinterface ()) {class <?> keytype = Descriptor.getMapKeyType (); if (keytype == null ||! string.class.issignableFrom (keytype)) {if (Descriptor.isRequired ()) {werfen Sie eine neue FatalbeanException aus ("Key Type [" + keytype + "] von Karte [" + type.getName () + "] muss [java.Lang.Lang.Lang.string]"; } return null; } Class <?> ValuEType = Descriptor.getMapvalUeType (); if (valuEType == null) {if (Descriptor.isRequired ()) {werfen Sie eine neue FatalbeanException aus ("kein Werttyp für MAP [" + type.getName () + "]"); } return null; } Map <String, Object> MatchingBeans = findAutoWirecandidates (Beanname, ValuEType, Deskriptor); if (MatchingBeans.isempty ()) {if (Descriptor.isrequired ()) {RaisenosuchbeandeFinitionException (Valuetype, "MAP With Value type" + ValueType.getName (), Descriptor); } return null; } if (AutoWiredBeannames! } return MatchingBeans; } else {map <String, Object> MatchingBeans = findAutoWirecandidates (Beanname, Typ, Deskriptor); if (matchingBeans.isempty ()) {if (Descriptor.isrequired ()) {RaisenosuchbeandeFinitionException (Typ, "", Deskriptor); } return null; } if (matchingBeans.SIZE ()> 1) {String primaryBeanname = besttPrimaryCandidat (MatchingBeans, Deskriptor); if (primaryBeanname == null) {werfen neu nuniqueBeNdeFinitionException (Typ, MatchingBeans.Keyset ()); } if (AutoWiredBeannames! } return MatchingBeans.get (primärbeAnname); } // Wir haben genau ein Match. Map.Entry <String, Object> Eintrag = MatchingBeans.EntrySet (). Iterator (). Next (); if (AutoWiredBeannames! } return Entry.getValue (); }}Wenn es sich um ein Array, eine Sammlung oder eine Karte handelt, die nach Typ gemäß dem Typ des Elements in der Sammlungsklasse automatisch ist (der Typ der Karte verwendet Wert). Warum ist es so besonders? Es stellt sich heraus, dass der Frühling für diesen Zweck ist: Sie können alle Implementierungen injizieren, die gleichzeitig übereinstimmen, dh Sie können sie wie folgt injizieren:
@Autowired
Private List <Car> Autos;
Wenn Ihr Auto mehrere Implementierungen hat, wird es injiziert und wird nicht erneut gemeldet
org.springframework.beans.factory.nosuchbeandefinitionException: Keine einzigartige Bean von Typ [me.arganzheng.study.spring.autowired.car] ist definiert: Erwartete Single -Matching -Bohne, fand 2: [Audi, Toyota].
Wenn Sie jedoch @Resource verwenden, haben Sie dieses Problem jedoch nicht:
public class AutoWiredTest erweitert BaseSpringtestCase {@resource @Qualifier ("LanguageChangesMap") private Karte <String, String> Languagechangesmap; @Test public void testAutowired () {AssertnotNull (Languagechangesmap); System.out.println (LanguageChangesmap.getClass (). GetImlenname ()); System.out.println (Languagechangesmap); }}Normaler Betrieb:
LinkedHasMap {pt = pt, br = pt, jp = ja, ja = ja, ind = ind, id = ind, en-rin = en-rin, in = en-rin, en = en, gb = en, th = th, ar = ar, eg = ar} Wenn Sie @Qualifier ("Languagechangesmap") nicht angeben und der Feldname nicht langeragechangesmap ist, wird derselbe Fehler weiterhin gemeldet.
Verursacht durch: org.springframework.bean.factory.nosuchbeandeFinitionException: Keine qualifizierende Bean von Typ [Java.lang.String] für die Abhängigkeit gefunden [Karte mit dem Wert -Typ -Typ Java.lang.String]: Erwartet mindestens 1 Bean, die als Autowire -Kandidat für diese Abhängigkeit qualifiziert sind. Abhängigkeitsanmerkungen: {@javax.annotation.resource (Sharable = true, MapedName =, Beschreibung =, name =, type = class Java.lang.Object, AuthenticationType = Container, Lookup =)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raisenosuchbeandeFinitionException (StandardsListableBeanFactory.java:986) at org.springFramework.beans.factory.support.DefaultListableBeanFactory.DoresoldePendency (DefaultListableBeanFactory.java:843) bei org.springFramework.bean.factory.Support.DefaultableListableBeAnfactory. org.springframework.context.annotation.CommonannotationBeanPostProcessor.autoWireresource (CommonannotationBeanPostProcessor.java:438) at org.springframework.context.annotation.CommonannotationBeanPostProcessor.getResource (CommonannotationBeanPostProcessor.java:416) unter org.springframework.context.annotation.CommonannotationBeanPostProcessor $ ressourcenelement.getResourcetoinject (CommonannotationBeanPostProcessor.java:550) at org.springframework.beans.factory.annotation.injectionMetadata $ injectedElement.inject (InjectionMetadata.java:150) bei org.springFramework.bean.factory.Anntion.InjectionMetadata.inject (InjectionMetadadata.java:87) ATRECTION. org.springframework.context.annotation.CommonannotationBeanPostProcessor.PostProcessPropertyValues (CommonannotationBeanPostProcessor.java:303) ... 26 weitereDarüber hinaus kann @Resource die obige Liste auch implementieren, um alle Implementierungen zu erhalten:
public class AutoWiredTest erweitert BaseSpringtestCase {@resource @Qualifier ("LanguageChangesMap") private Karte <String, String> Languagechangesmap; @Resource Private List <Car> Autos; @Test public void testAutowired () {AssertnotNull (Languagechangesmap); System.out.println (LanguageChangesmap.getClass (). GetImlenname ()); System.out.println (Languagechangesmap); Assertnotnull (Autos); System.out.println (cars.getClass (). GetImpleName ()); System.out.println (CARS); }}Richtig laufen:
LinkedHasMap {pt = pt, br = pt, jp = ja, ja = ja, ind = ind, id = ind, en-rin = en-rin, in = en-rin, en = en, gb = en, th = th, ar = ar, eg = ar} ArrayList [me.arganzheng.study.spring.autowired.audi@579584da, me.arganzheng.study.spring.autowired.toyota@1945312]
Dies liegt daran, dass die @Resource -Annotation den CommonannotationBeanPostProcessor -Prozessor verwendet, der nicht derselbe Autor wie AutoWiredAnnotationBeanPostProcessor [/Smile] ist. Ich werde es hier nicht analysieren. Interessierte Schüler können den Code lesen und selbst studieren.
Die endgültige Schlussfolgerung lautet wie folgt :
1. @autowired und @inject
Autowire nach Typ kann explizit von @Qualifier (Nicht-Sammelklasse. Hinweis: Nicht automatisch mit Bean-Namen!) angegeben werden!)
Wenn nach Typ fehlschlägen (nicht gefunden werden oder mehrere Implementierungen gefunden werden), degeneriert sie nach Feldname (Nicht-Sammelklasse), um automatisch zu automatisieren.
2. @Resource
Standard automatisch mit Feldnamen
Wenn der per Feldnamen automatisierte automatische Namen fehlschlägt, degeneriert er in automatisch nach Typ verankert.
Automatisch mit dem Qualifikationsnamen kann explizit über @Qualifier angegeben werden
Wenn der nach dem Qualifikationsnamen automatisierte automatische Namen fehlschlägt, entartet er sich mit dem Feldnamen in den automatischen Feld. Wenn der automatische durch Feldnamen fehlgeschlagen ist, wird er nicht mehr nach Typ bewegt. Das Testprojekt wird auf GitHub gespeichert. Es ist ein Standard -Maven -Projekt. Interessierte Schüler können es lokal klonen, um den Test durchzuführen.
Wieder auffüllen
Ein Kollege wies darauf hin, dass es im offiziellen Dokument von Spring einen Satz gibt, das mit meiner Beziehung in Konflikt steht:
Obwohl Sie diese Konvention verwenden können, um sich auf bestimmte Bohnen mit dem Namen zu verweisen, handelt es sich bei @autowired grundsätzlich um die typgesteuerte Injektion mit optionalen semantischen Qualifikationsgebern. Dies bedeutet, dass Qualifikationswerte auch mit dem Bean -Name Fallback immer eine Verengung der Semantik innerhalb der Typ -von Typ -Übereinstimmungen haben. Sie drücken nicht semantisch einen Hinweis auf eine eindeutige Bohnen -ID aus.
Mit anderen Worten, auch wenn @Autowired mit @Qualifier Annotation hinzugefügt wird, wird es tatsächlich nach Typ automatisch. @Qualifier ist nur ein Qualifikationsspiel, nur eine Filterbedingung. Ich habe den Code verfolgt und festgestellt, dass dies tatsächlich der Fall ist. Dieser von Spring entworfene @Qualifier -Name entspricht nicht dem Bean -Namen. Er ist ein bisschen ähnlich wie ein Tag. Wenn dieses Tag jedoch eindeutig ist, entspricht der Effekt tatsächlich dem Bean -Namen. In Bezug auf die Implementierung, Spring First GetByType, erhalten Sie Listenkandidaten und filtern Sie dann gemäß dem Namen des Qualifikationsspielers.
Definieren Sie einen anderen Lamborghini, hier wird @Qualifier angegeben:
Paket me.arganzheng.study.spring.autowired; import org.springframework.beans.factory.annotation.qualifier; import org.springframework.stereotype.comPonent; @Component @Qualifier ("Luxus") öffentliche Klasse Lamborghini implementiert Car {}Definieren Sie einen anderen Rolls-Royce, hier wird es absichtlich mit @Named angegeben:
Paket me.arganzheng.study.spring.autowired; Javax.inject.named importieren; import org.springframework.stereotype.comPonent; @Component @named ("Luxus") öffentliche Klasse Rollsroyce implementiert Car {} Testen Sie das Luxusauto mit injizierter Definition:
Paket me.arganzheng.study.spring.autowired; static junit.framework.assert.assertnotnull; importieren java.util.list; import me.arganzheng.study.baseSpringtestCase; import org.junit.test; import org.springframework.beans.factory.annotation.autowired; import org.springframework.beans.factory.annotation.qualifier; / ** * * @Author Zhengzhibin * */ public class AutowiredTest erweitert BaseSpringtestCase {@autowired @Qualifier ("Luxus") Private List <Car> LuxuryCars; @Test public void testAutowired () {Assertnotnull (Luxuscars); System.out.println (LuxuryCars.getClass (). GetImlenname ()); System.out.println (Luxuscars); }}Die Betriebsergebnisse sind wie folgt:
ArrayList [me.arganzheng.study.spring.autowired.lamborghini@66b875e1, me.arganzheng.study.spring.autowired.rollsroyce@58433b76]
Ergänzung: Autodiring -Modi
Frühling unterstützt vier Autowire -Modi. Bei Verwendung von XML -Konfigurationsmethoden können Sie diese über das AutoWire -Attribut angeben.
NEIN. (Standard) Keine AutoWiring. Bean -Referenzen müssen über ein Ref -Element definiert werden. Das Ändern der Standardeinstellung wird für größere Bereitstellungen nicht empfohlen, da die Angabe von Mitarbeitern ausdrücklich mehr Kontrolle und Klarheit ergeben. In gewissem Maße dokumentiert es die Struktur eines Systems. Byname. Automatisieren durch Eigenschaftsname. Spring sucht nach einer Bohne mit demselben Namen wie die Eigenschaft, die automatisiert werden muss. Wenn beispielsweise eine Bean -Definition mit Namen auf AutoWire festgelegt wird und eine Master -Eigenschaft (dh eine SetMaster -Methode (..)) enthält, sucht Spring nach einer Bean -Definition namens Master und verwendet sie, um die Eigenschaft festzulegen. Bytype. Ermöglicht eine Immobilie, wenn genau eine Bohne des Eigenschaftstyps im Container vorhanden ist. Wenn mehr als eins vorhanden ist, wird eine tödliche Ausnahme ausgelöst, was darauf hinweist, dass Sie möglicherweise nicht Bytype -Autowering für diese Bohne verwenden. Wenn es keine passenden Bohnen gibt, passiert nichts; Die Eigenschaft ist nicht festgelegt. Konstruktor. Analog zu Bytype, aber für Konstruktorargumente gelten. Wenn es nicht genau eine Bohne des Konstruktor -Argumententyps im Container gibt, wird ein tödlicher Fehler erhöht.
Wenn Sie @AutoWired, @Inject oder @Resource -Anmerkungen verwenden, wird dies etwas komplizierter sein, und es wird einen fehlgeschlagenen Verschlechterungsprozess geben, und ein Qualifikator wird eingeführt. Aber das Grundprinzip ist das gleiche.