Huzalozás tavasszal: @Autowired, @Resource és @Inject

1. Áttekintés

Ez a tavaszi keretrendszer bemutatja a függőség-injektálással kapcsolatos megjegyzések, nevezetesen a @Forrás, @ Injekció, és @Autowired annotációk. Ezek a jelölések az osztályoknak deklaratív módon biztosítják a függőségek megoldását. Például:

@Autowired ArbitraryClass arbObject;

a közvetlen példamutatással szemben (az imperatív módon), például:

ArbitraryClass arbObject = new ArbitraryClass ();

A három kommentár közül kettő a Java kiterjesztési csomaghoz tartozik: javax.annotation.Resource és javax.inject.Inject. A @Autowired az annotáció a org.springframework.beans.factory.annotation csomag.

Ezeknek az annotációknak a helyszíni injekcióval vagy szetter-injektálással lehet megoldani a függőségeket. Egyszerűsített, de gyakorlati példát fogunk használni a három annotáció közötti különbségtétel bemutatására, az egyes annotációk végrehajtási útvonalai alapján.

A példák arra összpontosítanak, hogy miként lehet használni a három injekciójegyzést az integrációs tesztelés során. A teszt által megkövetelt függőség lehet tetszőleges fájl vagy tetszőleges osztály.

2. A @Forrás Ajelölés

A @Forrás az annotáció a JSR-250 annotációs gyűjtemény része, és a Jakarta EE-hez van csomagolva. Ennek a kommentárnak a következő végrehajtási útvonalai vannak, elsőbbség szerint felsorolva:

  1. Név szerinti egyezés
  2. Egyezés típus szerint
  3. Mérkőzés selejtező szerint

Ezek a végrehajtási utak mind szetter, mind terepi injektálásra alkalmazhatók.

2.1. Terepi injekció

A függőségek terepi injekcióval történő megoldása úgy érhető el, hogy egy példányváltozót a @Forrás annotáció.

2.1.1. Név szerinti egyezés

A mérkőzésenkénti mező-injektálás bemutatására használt integrációs teszt a következőképpen szerepel:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = AnnotationConfigContextLoader.class, class = ApplicationContextTestResourceNameType.class) public class FieldResourceInjectionIntegrationTest {@Resource (name = "defaultFile"; @Test public void givenResourceAnnotation_WhenOnField_ThenDependencyValid () {assertNotNull (defaultFile); assertEquals ("namedFile.txt", defaultFile.getName ()); }}

Menjünk át a kódon. Ban,-ben FieldResourceInjectionTest integrációs teszt, a 7. sorban a név szerinti függőség feloldása úgy érhető el, hogy a bab nevét attribútumként adjuk át a @Forrás kommentár:

@Resource (name = "namedFile") privát fájl defaultFile;

Ez a konfiguráció a függőségeket a mérkőzésenkénti végrehajtási útvonal segítségével oldja meg. A bab namedFile meg kell határozni a ApplicationContextTestResourceNameType alkalmazás összefüggései.

Vegye figyelembe, hogy a babazonosítónak és a hozzá tartozó referenciaattribútum-értéknek meg kell egyeznie:

@Configuration public class ApplicationContextTestResourceNameType {@Bean (name = "namedFile") public File namedFile () {File namedFile = new File ("namedFile.txt"); return névFile; }}

Ha nem definiálja a babot az alkalmazás kontextusában, a org.springframework.beans.factory.NoSuchBeanDefinitionException dobják. Ez a programba beillesztett attribútumérték megváltoztatásával bizonyítható @Bab annotáció, a ApplicationContextTestResourceNameType az alkalmazás kontextusa; vagy megváltoztatja a @Forrás annotáció, a FieldResourceInjectionTest integrációs teszt.

2.1.2. Egyezés típus szerint

Az egyezés szerinti végrehajtási útvonal bemutatásához egyszerűen távolítsa el az attribútum értékét a 7. sorból FieldResourceInjectionTest integrációs teszt, hogy a következőképpen nézzen ki:

@Resource private File defaultFile;

és futtassa újra a tesztet.

A teszt akkor is sikeres lesz, mert ha a @Forrás az annotáció nem kap babnevet attribútumértékként, a Spring Framework folytatja a következő elsőbbségi szintet, típusonkénti egyezéssel, hogy megpróbálja megoldani a függőséget.

2.1.3. Mérkőzés selejtező szerint

A match-by-minősítő végrehajtási útvonal bemutatásához az integrációs tesztelési forgatókönyvet úgy módosítják, hogy két bab legyen meghatározva a ApplicationContextTestResourceQualifier alkalmazás kontextus:

@Configuration public class ApplicationContextTestResourceQualifier {@Bean (name = "defaultFile") public File defaultFile () {File defaultFile = new File ("defaultFile.txt"); return defaultFile; } @Bean (name = "namedFile") nyilvános FileFile () {File namedFile = új fájl ("namedFile.txt"); return névFile; }}

A QualifierResourceInjectionTest integrációs tesztet fogunk használni a mérkőzésenkénti selejtező függőségi felbontásának bemutatására. Ebben a forgatókönyvben egy adott babfüggőséget kell beadni minden referencia változóba:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = AnnotationConfigContextLoader.class, class = ApplicationContextTestResourceQualifier.class) public class QualifierResourceInjectionIntegrationTest {@Resource private File dependency1; @Forrás privát fájlfüggőség2; @Test public void givenResourceAnnotation_WhenField_ThenDependency1Valid () {assertNotNull (dependency1); assertEquals ("defaultFile.txt", dependency1.getName ()); } @Test public void givenResourceQualifier_WhenField_ThenDependency2Valid () {assertNotNull (dependency2); assertEquals ("namedFile.txt", dependency2.getName ()); }}

Futtassa az integrációs tesztet, és egy org.springframework.beans.factory.NoUniqueBeanDefinitionException dobják. Ezt a kivételt azért dobják el, mert az alkalmazás kontextusa két típusú babdefiníciót talált File, és zavaros, hogy melyik babnak kell megoldania a függőséget.

A probléma megoldásához olvassa el a dokumentum 7 - 10 sorát QualifierResourceInjectionTest integrációs teszt:

@Forrás privát fájlfüggőség1; @Forrás privát fájlfüggőség2;

és adja hozzá a következő kódsorokat:

@Qualifier ("defaultFile") @Qualifier ("namedFile")

úgy, hogy a kódblokk a következőképpen nézzen ki:

@Resource @Qualifier ("defaultFile") privát fájlfüggőség1; @Resource @Qualifier ("namedFile") privát fájlfüggőség2;

Futtassa újra az integrációs tesztet, ezúttal át kell mennie. Ennek a tesztnek az volt a célja, hogy bemutassa, hogy még akkor is, ha egy alkalmazás összefüggésében több bab van meghatározva, a @ Minősítő az annotáció tisztázza az esetleges zavart azáltal, hogy lehetővé teszi bizonyos függőségek injekciózását egy osztályba.

2.2. Setter injekció

A függőségek mezőbe történő injektálásakor végrehajtott útvonalak szetter alapú injektálásra alkalmazhatók.

2.2.1. Név szerinti egyezés

Az egyetlen különbség a MethodResourceInjectionTest az integrációs teszt szetter módszerrel rendelkezik:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = AnnotationConfigContextLoader.class, class = ApplicationContextTestResourceNameType.class) public class MethodResourceInjectionIntegrationTest {private File defaultFile; @Resource (name = "namedFile") védett void setDefaultFile (File defaultFile) {this.defaultFile = defaultFile; } @Test public void givenResourceAnnotation_WhenSetter_ThenDependencyValid () {assertNotNull (defaultFile); assertEquals ("namedFile.txt", defaultFile.getName ()); }}

A függőségek szetter injekcióval történő megoldása egy referencia változó megfelelő szetter módszerének feljegyzésével történik. Adja át a babfüggőség nevét attribútumértékként a @Forrás kommentár:

privát fájl defaultFile; @Resource (name = "namedFile") védett void setDefaultFile (File defaultFile) {this.defaultFile = defaultFile; }

A namedFile a babfüggőséget ebben a példában újra felhasználják. A babnévnek és a hozzá tartozó attribútumértéknek meg kell egyeznie.

Futtassa az integrációs tesztet a jelenlegi állapotában, és ez sikeres lesz.

Annak megtekintéséhez, hogy a függőséget valóban a mérkőzésenkénti végrehajtási útvonal oldotta meg, módosítsa a @Forrás jelölést az Ön által választott értékre, és futtassa újra a tesztet. Ezúttal a teszt kudarcot vall a NoSuchBeanDefinitionException.

2.2.2. Egyezés típus szerint

A szetter alapú, egyezés szerinti végrehajtás bemutatásához a MethodByTypeResourceTest integrációs teszt:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = AnnotationConfigContextLoader.class, class = ApplicationContextTestResourceNameType.class) public class MethodByTypeResourceIntegrationTest {private File defaultFile; @ Resource protected void setDefaultFile (File defaultFile) {this.defaultFile = defaultFile; } @Test public void givenResourceAnnotation_WhenSetter_ThenValidDependency () {assertNotNull (defaultFile); assertEquals ("namedFile.txt", defaultFile.getName ()); }}

Futtassa ezt a tesztet olyan állapotban, amely sikeres lesz.

Annak ellenőrzése érdekében, hogy a File a függőséget valóban megoldotta a mérkőzésenkénti végrehajtási útvonal, változtassa meg az osztály típusát defaultFile változó egy másik osztálytípusra, mint például Húr. Végezze el a MethodByTypeResourceTest integrációs teszt újra és ezúttal a NoSuchBeanDefinitionException dobni fogják.

A kivétel igazolja, hogy a megoldást valóban típusonkénti egyezéssel használták File függőség. A NoSuchBeanDefinitionException megerősíti, hogy a referencia változó nevének nem kell egyeznie a bab nevével. Ehelyett a függőség felbontása attól függ, hogy a bab osztálytípusa megegyezik-e a referencia változó osztálytípusával.

2.2.3. Mérkőzés selejtező szerint

A MethodByQualifierResourceTest integrációs tesztet fogunk használni, hogy bemutassuk a match-by-minősítő végrehajtási útvonalát:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = AnnotationConfigContextLoader.class, class = ApplicationContextTestResourceQualifier.class) public class MethodByQualifierResourceIntegrationTest {private File arbDependency; privát Fájl egy másikArbDependency; @Test public void givenResourceQualifier_WhenSetter_ThenValidDependencies () {assertNotNull (arbDependency); assertEquals ("namedFile.txt", arbDependency.getName ()); assertNotNull (anotherArbDependency); assertEquals ("defaultFile.txt", anotherArbDependency.getName ()); } @Resource @Qualifier ("namedFile") public void setArbDependency (File arbDependency) {this.arbDependency = arbDependency; } @Resource @Qualifier ("defaultFile") public void setAnotherArbDependency (File anotherArbDependency fájl) {this.anotherArbDependency = anotherArbDependency; }}

Ennek a tesztnek a célja annak bemutatása, hogy még akkor is, ha egy alkalmazás kontextusában egy adott típusú többféle babkivitelezés van meghatározva, a @ Minősítő annotáció használható a @Forrás annotáció a függőség megoldására.

Hasonlóan a terepi alapú függőség-injektáláshoz, ha egy alkalmazás összefüggésében több bab van meghatározva, a NoUniqueBeanDefinitionException dobják, ha nem @ Minősítő annotációval lehet meghatározni, hogy melyik babot kell használni a függőségek feloldására.

3. Az @ Injekció Megjegyzés

A @ Injekció az annotáció a JSR-330 annotációk gyűjteményéhez tartozik. Ennek a kommentárnak a következő végrehajtási útvonalai vannak, elsőbbség szerint felsorolva:

  1. Egyezés típus szerint
  2. Mérkőzés selejtező szerint
  3. Név szerinti egyezés

Ezek a végrehajtási utak mind szetter, mind terepi injektálásra alkalmazhatók. A @ Injekció kommentár, a javax.injekció a könyvtárat Gradle vagy Maven függőségként kell deklarálni.

Gradle esetében:

testCompile csoport: 'javax.inject', név: 'javax.inject', verzió: '1'

Maven számára:

 javax.inject javax.inject 1 

3.1. Terepi injekció

3.1.1. Egyezés típus szerint

Az integrációs teszt példája egy másik típusú függőség, nevezetesen a ÖnkényesFüggőség osztály. A ÖnkényesFüggőség az osztályfüggőség csupán egyszerű függőségként szolgál, és nincs további jelentősége. A következőképpen szerepel:

@Component public class ArbitraryDependency {private final String label = "Önkényes függőség"; public String toString () {return label; }}

A FieldInjectTest a kérdéses integrációs teszt a következőképpen szerepel:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = AnnotationConfigContextLoader.class, class = ApplicationContextTestInjectType.class) public class FieldInjectIntegrationTest {@Inject private ArbitraryDependency fieldInjectDependency; @Test public void givenInjectAnnotation_WhenOnField_ThenValidDependency () {assertNotNull (fieldInjectDependency); assertEquals ("Önkényes függőség", fieldInjectDependency.toString ()); }}

ellentétben a @Forrás annotáció, amely először a név alapján oldja fel a függőségeket; a. alapértelmezett viselkedése @ Injekció az annotáció típusonként oldja meg a függőségeket.

Ez azt jelenti, hogy még akkor is, ha egy osztály referencia változó neve eltér a bab nevétől, a függőség továbbra is megoldódik, feltéve, hogy a bab meghatározása az alkalmazás kontextusában történik. Vegye figyelembe, hogy a referenciaváltozó neve a következő tesztben:

@ Inject private ArbitraryDependency mezőInjectDependency;

eltér az alkalmazáskörnyezetben konfigurált babnévtől:

@Bean public ArbitraryDependency injectDependency () {ArbitraryDependency injectDependency = new ArbitraryDependency (); return injectDependency; }

és amikor a teszt végrehajtásra kerül, képes megoldani a függőséget.

3.1.2. Mérkőzés selejtező szerint

De mi van akkor, ha egy adott osztálytípusnak több megvalósítása is van, és egy adott osztályhoz külön bab szükséges? Módosítsuk az integrációs tesztelési példát úgy, hogy újabb függőségre van szükség.

Ebben a példában a ÖnkényesFüggőség osztály, amelyet a match-by-type példában használnak a AnotherArbitraryDependency osztály:

public class A AnotherArbitraryDependency kiterjeszti az ArbitraryDependency {private final String label = "Egy másik önkényes függőség"; public String toString () {return label; }}

Minden teszteset célja annak biztosítása, hogy az egyes függőségeket megfelelően injektálják az egyes referenciaváltozókba:

@ Inject private ArbitraryDependency defaultDependency; @Inject private ArbitraryDependency namedDependency;

A FieldQualifierInjectTest a selejtező szerinti egyezés bemutatására használt integrációs teszt a következő:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = AnnotationConfigContextLoader.class, class = ApplicationContextTestInjectQualifier.class) public class FieldQualifierInjectIntegrationTest {@Inject private ArbitraryDependency defaultDependency; @Inject private ArbitraryDependency namedDependency; @Test public void givenInjectQualifier_WhenOnField_ThenDefaultFileValid () {assertNotNull (defaultDependency); assertEquals ("Önkényes függőség", defaultDependency.toString ()); } @Test public void givenInjectQualifier_WhenOnField_ThenNamedFileValid () {assertNotNull (defaultDependency); assertEquals ("Egy másik önkényes függőség", a neveDependency.toString ()); }}

Ha egy alkalmazáskörnyezetben egy adott osztálynak több megvalósítása van, akkor a FieldQualifierInjectTest az integrációs teszt megkísérli a függőségek injektálását az alább felsorolt ​​módon:

@ Inject private ArbitraryDependency defaultDependency; @Inject private ArbitraryDependency namedDependency;

a NoUniqueBeanDefinitionException dobni fogják.

Ennek a kivételnek a dobása a Spring Framework módja annak rámutatására, hogy egy adott osztálynak több implementációja van, és zavaros, hogy melyiket kell használni. A zavart tisztázása érdekében lépjen a 7. és 10. sorra FieldQualifierInjectTest integrációs teszt:

@ Inject private ArbitraryDependency defaultDependency; @Inject private ArbitraryDependency namedDependency;

adja át a szükséges babnevet a @ Minősítő annotáció, amelyet a @ Injekció annotáció. A kódblokk most a következőképpen fog kinézni:

@Inject @Qualifier ("defaultFile") privát ArbitraryDependency defaultDependency; @Inject @Qualifier ("namedFile") privát ArbitraryDependency namedDependency;

A @ Minősítő az annotáció szigorú egyezést vár el, amikor babnevet kap. Győződjön meg arról, hogy a bab nevét átadta a Minősítő helyesen, különben a NoUniqueBeanDefinitionException dobni fogják. Futtassa újra a tesztet, és ezúttal át kell mennie.

3.1.3. Név szerinti egyezés

A FieldByNameInjectTest a név szerinti egyezés bemutatásához használt integrációs teszt hasonló a típus szerinti egyezés végrehajtási útvonalához. Az egyetlen különbség az, hogy egy adott babra van szükség, szemben egy adott típussal. Ebben a példában a ÖnkényesFüggőség osztály ismét elő a MégisAnotherArbitraryDependency osztály:

public class YetAnotherArbitraryDependency kiterjeszti ArbitraryDependency {private final String label = "Még egy önkényes függőség"; public String toString () {return label; }}

A mérkőzésenkénti végrehajtási útvonal bemutatásához a következő integrációs tesztet fogjuk használni:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (betöltő = AnnotationConfigContextLoader.class, class = ApplicationContextTestInjectName.class) nyilvános osztály FieldByNameInjectIntegrationTest {@Inject @Names ("yetAnotherFieldInject; @Test public void givenInjectQualifier_WhenSetOnField_ThenDependencyValid () {assertNotNull (yetAnotherFieldInjectDependency); assertEquals ("Még egy önkényes függőség", yetAnotherFieldInjectDependency.toString ()); }}

Az alkalmazás kontextusát a következőképpen soroljuk fel:

@Configuration public class ApplicationContextTestInjectName {@Bean public ArbitraryDependency yetAnotherFieldInjectDependency () {ArbitraryDependency yetAnotherFieldInjectDependency = new YetAnotherArbitraryDependency (); return yetAnotherFieldInjectDependency; }}

Futtassa az integrációs tesztet úgy, ahogy van, és ez sikeres lesz.

Annak ellenőrzése érdekében, hogy a függőséget valóban a mérkőzésenkénti végrehajtási útvonal injektálta-e, módosítsa az értéket, yetAnotherFieldInjectDependency, amelyet átadtak a @Nevezett annotáció egy másik választott névhez. Futtassa újra a tesztet - ezúttal a NoSuchBeanDefinitionException dobják.

3.2. Setter injekció

Szetter alapú injekció a @ Injekció az annotáció hasonló az alkalmazott megközelítéshez @Forrás szetter alapú injekció. A referencia változó feliratozása helyett a megfelelő setter metódust jegyzik fel. A végrehajtási utak, amelyeket a terepi függőség injektálása követ, a szetter alapú injekciókra is vonatkoznak.

4. A @Autowired Megjegyzés

- viselkedése @Autowired annotáció hasonló a @ Injekció annotáció. Az egyetlen különbség az, hogy a @Autowired az annotáció a tavaszi keret része. Ennek a kommentárnak ugyanazok a végrehajtási útvonalai vannak, mint a @ Injekció feljegyzés, fontossági sorrendben felsorolva:

  1. Egyezés típus szerint
  2. Mérkőzés selejtező szerint
  3. Név szerinti egyezés

Ezek a végrehajtási utak mind szetter, mind terepi injektálásra alkalmazhatók.

4.1. Terepi injekció

4.1.1. Egyezés típus szerint

Az integráció tesztelési példája a @Autowired a mérkőzésenkénti végrehajtási útvonal hasonló lesz a teszt bemutatásához, amelyet a @ Injekció match-by-type végrehajtási útvonal. A FieldAutowiredTest integrációs teszt, amelyet az egyeztetés típusonkénti bemutatására használnak a @Autowired a kommentár a következőképpen szerepel:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = AnnotationConfigContextLoader.class, class = ApplicationContextTestAutowiredType.class) public class FieldAutowiredIntegrationTest {@Autowired private ArbitraryDependency fieldDependence; @Test public void givenAutowired_WhenSetOnField_ThenDependencyResolved () {assertNotNull (fieldDependency); assertEquals ("Önkényes függőség", fieldDependency.toString ()); }}

Ennek az integrációs tesztnek az alkalmazási környezete a következő:

@Configuration public class ApplicationContextTestAutowiredType {@Bean public ArbitraryDependency autowiredFieldDependency () {ArbitraryDependency autowiredFieldDependency = new ArbitraryDependency (); return autowiredFieldDependency; }}

Az integrációs teszt célja annak bemutatása, hogy a típusonkénti egyezés elsőbbséget élvez a többi végrehajtási útvonallal szemben. Értesítés a FieldAutowiredTest integrációs teszt, hogy a referencia változó neve:

@Autowired private ArbitraryDependency fieldDependency;

eltér a bab nevétől az alkalmazás összefüggésében:

@Bean public ArbitraryDependency autowiredFieldDependency () {ArbitraryDependency autowiredFieldDependency = new ArbitraryDependency (); return autowiredFieldDependency; }

Amikor a teszt lefut, átmegy.

Annak megerősítése érdekében, hogy a függőség valóban megoldódott az egyezésenkénti végrehajtási útvonal használatával, módosítsa a típusát fieldDependency referencia változót, és futtassa újra az integrációs tesztet. Ezúttal a FieldAutowiredTest az integrációs tesztnek meg kell buknia, a NoSuchBeanDefinitionException dobják. Ez ellenőrzi, hogy típusonkénti egyezést használtak-e a függőség feloldására.

4.1.2. Mérkőzés selejtező szerint

Mi van, ha olyan helyzetben van, amikor az alkalmazás kontextusában többféle bab-implementációt határoztak meg, például az alábbiakban felsoroltakhoz:

@Configuration public class ApplicationContextTestAutowiredQualifier {@Bean public ArbitraryDependency autowiredFieldDependency () {ArbitraryDependency autowiredFieldDependency = new ArbitraryDependency (); return autowiredFieldDependency; } @Bean public ArbitraryDependency anotherAutowiredFieldDependency () {ArbitraryDependency anotherAutowiredFieldDependency = new AnotherArbitraryDependency (); return anotherAutowiredFieldDependency; }}

Ha a FieldQualifierAutowiredTest az alább felsorolt ​​integrációs teszt végrehajtásra kerül:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = AnnotationConfigContextLoader.class, class = ApplicationContextTestAutowiredQualifier.class) public class FieldQualifierAutowiredIntegrationTest {@Autowired private field ArbitraryDepend @Autowired private ArbitraryDependency fieldDependency2; @Test public void givenAutowiredQualifier_WhenOnField_ThenDep1Valid () {assertNotNull (fieldDependency1); assertEquals ("Önkényes függőség", fieldDependency1.toString ()); } @Test public void givenAutowiredQualifier_WhenOnField_ThenDep2Valid () {assertNotNull (fieldDependency2); assertEquals ("Egy másik önkényes függőség", fieldDependency2.toString ()); }}

a NoUniqueBeanDefinitionException dobni fogják.

A kivétel annak a kétértelműségnek köszönhető, amelyet az alkalmazás összefüggésében definiált két bab okoz. A Spring Framework nem tudja, melyik babfüggőséget mely referenciaváltozóhoz kell automatikusan bekötni. Oldja meg ezt a problémát a @ Minősítő kommentár a. 7. és 10. sorához FieldQualifierAutowiredTest integrációs teszt:

@Autowired private FieldDependency fieldDependency1; @Autowired private FieldDependency fieldDependency2;

úgy, hogy a kódblokk a következőképpen nézzen ki:

@Autowired @Qualifier ("autowiredFieldDependency") privát FieldDependency fieldDependency1; @Autowired @Qualifier ("anotherAutowiredFieldDependency") privát FieldDependency fieldDependency2;

Futtassa újra a tesztet, és ezúttal sikeres lesz.

4.1.3. Név szerinti egyezés

Ugyanezt az integrációs teszt forgatókönyvet fogják használni az egyezés szerinti végrehajtási útvonal bemutatására a @Autowired annotáció a mezőfüggőség injektálására. Amikor a függőségeket név szerint írja be, a @ComponentScan annotációt kell használni az alkalmazás kontextusában, ApplicationContextTestAutowiredName:

@Configuration @ComponentScan (basePackages = {"com.baeldung.dependency"}) public class ApplicationContextTestAutowiredName {}

A @ComponentScan az annotáció a Java osztályokhoz keresi a csomagokat, amelyekhez a @Összetevő annotáció. Például az alkalmazás kontextusában a com.baeldung.függőség A csomag ellenőrzi azokat az osztályokat, amelyekhez a @Összetevő annotáció. Ebben a forgatókönyvben a tavaszi keretnek fel kell fedeznie a ÖnkényesFüggőség osztály, amelynek a @Összetevő kommentár:

@Component (value = "autowiredFieldDependency") public class ArbitraryDependency {private final String label = "Önkényes függőség"; public String toString () {return label; }}

Az attribútum értéke, autowiredFieldDependency, átment a @Összetevő annotáció, elmondja a tavaszi keretrendszernek, hogy a ÖnkényesFüggőség osztály nevű komponens autowiredFieldDependency. Annak érdekében, hogy a @Autowired megjegyzés a függőségek név szerinti feloldásához, az összetevő nevének meg kell egyeznie a FieldAutowiredNameTest integrációs teszt; kérjük, olvassa el a 8. sort:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = AnnotationConfigContextLoader.class, class = ApplicationContextTestAutowiredName.class) public class FieldAutowiredNameIntegrationTest {@Autowired private ArbitraryDependency; @Test public void givenAutowiredAnnotation_WhenOnField_ThenDepValid () {assertNotNull (autowiredFieldDependency); assertEquals ("Önkényes függőség", autowiredFieldDependency.toString ()); }}

Amikor az FieldAutowiredNameTest az integrációs tesztet úgy futtatjuk, ahogy van, ez sikeres lesz.

De honnan tudjuk, hogy a @Autowired az annotáció valóban a match-by-name végrehajtási utat hívta meg? Módosítsa a referencia változó nevét autowiredFieldDependency másik névre, amelyet választott, majd futtassa újra a tesztet.

Ezúttal a teszt kudarcot vall, és a NoUniqueBeanDefinitionException dobják. Hasonló ellenőrzés lenne a @Összetevő attribútum értéke, autowiredFieldDependency, egy másik választott értékre, és futtassa újra a tesztet. A NoUniqueBeanDefinitionException dobni is fogják.

Ez a kivétel annak bizonyítéka, hogy helytelen babnév használata esetén nem található érvényes bab. Ezért a match-by-name végrehajtási útvonalat hívták meg.

4.2. Setter injekció

Szetter alapú injekció a @Autowired az annotáció hasonló a bemutatott megközelítéshez @Forrás szetter alapú injekció. Ahelyett, hogy a referencia változót a @ Injekció annotáció, a megfelelő szetter fel van jegyezve. A végrehajtási utak, amelyeket a terepi függőség-injektálás követ, a szetter-alapú injekciókra is érvényesek.

5. Ezen kommentárok alkalmazása

Ez felveti a kérdést, melyik annotációt kell használni és milyen körülmények között? A válasz ezekre a kérdésekre attól függ, hogy milyen tervezési szcenárióval kell szembenéznie a kérdéses alkalmazásnak, és hogy a fejlesztő hogyan kívánja kihasználni a polimorfizmust az egyes kommentárok alapértelmezett végrehajtási útvonalai alapján.

5.1. A szingletonok alkalmazási körű felhasználása a polimorfizmus révén

Ha a kialakítás olyan, hogy az alkalmazás viselkedése egy felület vagy egy absztrakt osztály megvalósításán alapul, és ezeket a viselkedéseket az alkalmazás egészében használják, akkor használja a @ Injekció vagy @Autowired annotáció.

Ennek a megközelítésnek az az előnye, hogy amikor az alkalmazást frissítik, vagy javítást kell alkalmazni a hiba kijavításához; akkor az osztályok felcserélhetők, minimális negatív hatással az alkalmazás általános viselkedésére. Ebben a forgatókönyvben az elsődleges alapértelmezett végrehajtási útvonal típusonkénti egyezés.

5.2. Finomszemcsés alkalmazás-viselkedés konfigurálása a polimorfizmus révén

Ha a kialakítás olyan, hogy az alkalmazás komplex viselkedéssel rendelkezik, minden viselkedés különböző interfészeken / absztrakt osztályokon alapul, és ezeknek a megvalósításoknak az alkalmazása az alkalmazásonként eltérő, akkor használja a @Forrás annotáció. Ebben a forgatókönyvben az elsődleges alapértelmezett végrehajtási útvonal név szerint egyezik.

5.3. A függőségi injekciót kizárólag a Jakarta EE Platformnak kell kezelnie

Ha van egy tervezési megbízás arra, hogy az összes függőséget a Jakarta EE Platform injektálja, és ne a Spring, akkor a választás a @Forrás kommentár és a @ Injekció annotáció. Szűkítenie kell a végső döntést a két kommentár között, amely alapján alapértelmezett végrehajtási útvonalra van szükség.

5.4. A függőség injekcióját kizárólag a tavaszi keretnek kell kezelnie

Ha a megbízás minden függőséget a tavaszi keretnek kell kezelnie, az egyetlen választás a @Autowired annotáció.

5.5. Beszélgetés összefoglalása

Az alábbi táblázat összefoglalja a vitát.

Forgatókönyv@Forrás@ Injekció@Autowired
A szingulettek felhasználása a polimorfizmus révén
Finomszemcsés alkalmazási viselkedés konfiguráció polimorfizmus révén
A függőség-injektálást kizárólag a Jakarta EE platformnak kell kezelnie
A függőség-injektálást kizárólag a tavaszi keretnek kell kezelnie

6. Következtetés

A cikk célja az volt, hogy mélyebb betekintést nyújtson az egyes annotációk viselkedésébe. Az egyes kommentárok viselkedésének megértése hozzájárul az alkalmazások átfogóbb tervezéséhez és karbantartásához.

A vita során használt kód megtalálható a GitHub oldalon.