A BeanDefinitionOverrideException a tavaszi rendszerindításban

1. Bemutatkozás

A Spring Boot 2.1 frissítés több embert is meglepett a váratlan eseményekkel BeanDefinitionOverrideException. Összezavarhatja egyes fejlesztőket, és elgondolkodtathatja őket abban, hogy mi történt a bab felülbíráló viselkedésével tavasszal.

Ebben az oktatóanyagban kibontjuk ezt a problémát, és megtudjuk, hogyan lehet a legjobban megoldani.

2. Maven-függőségek

A Maven-projektünkhöz hozzá kell adnunk a Spring Boot Starter függőséget:

 org.springframework.boot spring-boot-starter 2.3.3.FELHASZNÁLÁS 

3. Bab felülbírálása

A tavaszi babokat a nevükön belül azonosítják ApplicationContext.

Így, A bab felülírása egy alapértelmezett viselkedés, amely akkor történik, amikor egy babot definiálunk egy ApplicationContext amelynek ugyanaz a neve, mint egy másik babnak. Úgy működik, hogy névütközés esetén egyszerűen kicseréli a korábbi babot.

Az 5.1 tavasztól kezdődően a BeanDefinitionOverrideException azért vezették be, hogy a fejlesztők automatikusan kivethessék a kivételt, hogy megakadályozzák a váratlan bab felülírását. Alapértelmezés szerint az eredeti viselkedés továbbra is elérhető, amely lehetővé teszi a bab felülírását.

4. A tavaszi rendszerindítás konfigurációjának módosítása 2.1

A Spring Boot 2.1 védekezésként alapértelmezés szerint letiltotta a bab felülírását. A fő cél az, hogy előzetesen vegye figyelembe a másolt babneveket, hogy elkerülje a bab véletlen felülbírálását.

Ezért, ha a Spring Boot alkalmazásunk a bab felülbírálására támaszkodik, nagy valószínűséggel találkozik a BeanDefinitionOverrideException miután frissítettük a Spring Boot verziót 2.1-re és újabbra.

A következő szakaszokban megnézünk egy példát, ahol a BeanDefinitionOverrideException előfordulna, majd megbeszélünk néhány megoldást.

5. A bab azonosítása konfliktusban

Hozzunk létre két különböző tavaszi konfigurációt, amelyek mindegyikén van egy testBean () módszerrel előállítani a BeanDefinitionOverrideException:

@Configuration public class TestConfiguration1 {class TestBean1 {private String name; // standard getterek és beállítók} @Bean public TestBean1 testBean () {return new TestBean1 (); }} 
@Configuration public class TestConfiguration2 {class TestBean2 {private String name; // szokásos getterek és beállítók} @Bean public TestBean2 testBean () {return new TestBean2 (); }} 

Ezután elkészítjük a Spring Boot tesztosztályunkat:

@RunWith (SpringRunner.class) @SpringBootTest (class = {TestConfiguration1.class, TestConfiguration2.class}) public class SpringBootBeanDefinitionOverrideExceptionIntegrationTest {@Test public void whenBeanOverridingAllowed_thenTestBean2 (TestBean2) Test (Application) assertThat (testBean.getClass ()). isEqualTo (TestConfiguration2.TestBean2.class); }} 

A teszt lefuttatása a BeanDefinitionOverrideException. A kivétel azonban hasznos információkat nyújt számunkra:

Érvénytelen babdefiníció a "testBean" névvel definiálva ... ... com.baeldung.beandefinitionoverrideexception.TestConfiguration2 ... Nem lehet regisztrálni a babdefiníciót ... a 'testBean' bab esetében ... Már van [... definiálva a ... ... com.baeldung.beandefinitionoverrideexception.TestConfiguration1] fájlban. 

Vegye figyelembe, hogy a kivétel két fontos információt tár fel.

Az első az ütköző babnév, testBean:

Érvénytelen babdefiníció a 'testBean' névvel ... 

És a második megmutatja az érintett konfigurációk teljes útvonalát:

... com.baeldung.beandefinitionoverrideexception.TestConfiguration2 ... ... com.baeldung.beandefinitionoverrideexception.TestConfiguration1 ... 

Ennek eredményeként láthatjuk, hogy két különböző babot azonosítanak testBean konfliktust okoz. Ezenkívül a babot a konfigurációs osztályok tartalmazzák TestConfiguration1 és TestConfiguration2.

6. Lehetséges megoldások

Konfigurációnktól függően a Spring Beans alapértelmezett nevekkel rendelkezik, hacsak nem határozzuk meg őket kifejezetten.

Ezért az első lehetséges megoldás a babunk átnevezése.

Van néhány általános módszer a babnevek tavasszal történő beállítására.

6.1. Módszernevek módosítása

Alapértelmezés szerint, A tavasz bab névként veszi fel az annotált módszerek nevét.

Ezért, ha a konfigurációs osztályban definiálunk babot, mint például a példánk, akkor a metódusok egyszerű megváltoztatása megakadályozza a BeanDefinitionOverrideException:

@Bean public TestBean1 testBean1 () {return new TestBean1 (); } 
@Bean public TestBean2 testBean2 () {return new TestBean2 (); } 

6.2. @Bab Megjegyzés

Tavaszi @Bab az annotáció a bab meghatározásának nagyon gyakori módja.

Így egy másik lehetőség a név tulajdona @Bab kommentár:

@Bean ("testBean1") nyilvános TestBean1 testBean () {return new TestBean1 (); } 
@Bean ("testBean2") nyilvános TestBean1 testBean () {return new TestBean2 (); } 

6.3. Sztereotípiás kommentárok

A bab meghatározásának másik módja a sztereotípiás kommentárok. Tavaszival @ComponentScan funkció engedélyezve, a bab nevét osztály szinten definiálhatjuk a @Összetevő kommentár:

@Component ("testBean1") osztály TestBean1 {privát karakterlánc neve; // szabványos mérőeszközök és beállítók} 
@Component ("testBean2") osztály TestBean2 {privát karakterlánc neve; // szabványos mérőeszközök és beállítók} 

6.4. A harmadik fél könyvtáraiból származó bab

Egyes esetekben, névkonfliktusba ütközhet, amelyet a harmadik fél által támogatott könyvtárakból származó bab okoz.

Amikor ez megtörténik, meg kell próbálnunk azonosítani, hogy melyik ütköző bab tartozik az alkalmazásunkba, annak megállapítására, hogy a fenti megoldások bármelyike ​​alkalmazható-e.

Ha azonban nem tudjuk megváltoztatni a babdefiníciók egyikét sem, akkor a Spring Boot beállítása a bab felülírásának lehetővé tételével megkerülhetõ.

A bab felülírásának engedélyezéséhez állítsuk be a tavasz.főbb.allow-bab-definíció-felülbíráló tulajdonhoz igaz miénkben alkalmazás.tulajdonságok fájl:

tavasz.fõ.allow-bab-definíció-felülbíráló = igaz 

Ezzel azt mondjuk a Spring Bootnak, hogy engedélyezze a bab felülírását a babdefiníciók változása nélkül.

Utolsó értesítésként tudatában kell lennünk ennek nehéz kitalálni, hogy melyik babnak lesz elsőbbsége, mert a bab létrehozásának sorrendjét a futás közben leginkább befolyásolt függőségi viszonyok határozzák meg. Ezért a bab felülbírálásának engedélyezése váratlan viselkedést eredményezhet, hacsak nem ismerjük elég jól babunk függőségi hierarchiáját.

7. Következtetés

Ebben az oktatóanyagban elmagyaráztuk, mit BeanDefinitionOverrideException azt jelenti tavasszal, miért jelenik meg hirtelen, és hogyan lehet kezelni a Spring Boot 2.1 frissítés után.

Mint mindig, a cikk teljes forráskódja megtalálható a GitHubon.