BeanDefinitionOverrideException u proljetnom pokretanju

1. Uvod

Nadogradnja Spring Boot 2.1 iznenadila je nekoliko ljudi neočekivanim pojavama BeanDefinitionOverrideException. To može zbuniti neke programere i natjerati ih da se zapitaju o tome što se dogodilo s ponašanjem nadjačavanja graha u proljeće.

U ovom ćemo uputstvu razotkriti ovaj problem i vidjeti kako ga najbolje riješiti.

2. Ovisnosti Mavena

Za naš primjer Maven projekta moramo dodati ovisnost Spring Boot Starter:

 org.springframework.boot spring-boot-starter 2.3.3.OSLOBODI 

3. Zamjena graha

Proljetni grah prepoznaje se po imenima unutar ApplicationContext.

Tako, nadjačavanje graha je zadano ponašanje koje se događa kada definiramo grah unutar ApplicationContext koji ima isto ime kao i drugi grah. Djeluje jednostavnom zamjenom bivšeg zrna u slučaju sukoba imena.

Počevši od proljeća 5.1 BeanDefinitionOverrideException uveden je kako bi se programerima omogućilo da automatski izbace iznimku kako bi spriječili neočekivano nadjačavanje graha. Prema zadanim postavkama izvorno ponašanje i dalje je dostupno što omogućuje nadjačavanje graha.

4. Promjena konfiguracije za Spring Boot 2.1

Spring Boot 2.1 onemogućio je nadjačavanje graha prema zadanim postavkama kao obrambeni pristup. Glavna svrha je da unaprijed primijetite dvostruka imena graha kako biste slučajno spriječili nadjačavanje graha.

Stoga, ako se naša aplikacija Spring Boot oslanja na nadjačavanje graha, vrlo je vjerojatno da će naići na BeanDefinitionOverrideException nakon što nadogradimo verziju Spring Boot na 2.1 i novije verzije.

U sljedećim ćemo odjeljcima pogledati primjer gdje BeanDefinitionOverrideException i tada ćemo razgovarati o nekim rješenjima.

5. Prepoznavanje graha u sukobu

Stvorimo dvije različite konfiguracije Spring, svaka s oznakom testBean () metodom, za proizvodnju BeanDefinitionOverrideException:

@Configuration javna klasa TestConfiguration1 {class TestBean1 {naziv privatnog niza; // standardni getteri i postavljači} @Bean public TestBean1 testBean () {return new TestBean1 (); }} 
@Configuration javna klasa TestConfiguration2 {class TestBean2 {naziv privatnog niza; // standardni getteri i postavljači} @Bean public TestBean2 testBean () {return new TestBean2 (); }} 

Zatim ćemo stvoriti našu probnu klasu Spring Boot:

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

Izvođenje testa daje a BeanDefinitionOverrideException. Međutim, iznimka nam pruža neke korisne informacije:

Nevažeća definicija graha s imenom "testBean" definirana u ... ... com.baeldung.beandefinitionoverrideexception.TestConfiguration2 ... Ne može se registrirati definicija graha [... definirana u ... ... com.baeldung.beandefinitionoverrideexception.TestConfiguration2] za grah 'testBean' ... Već je vezan [... definiran u ... ... com.baeldung.beandefinitionoverrideexception.TestConfiguration1]. 

Primijetite da iznimka otkriva dvije važne informacije.

Prvo je sukobljeno ime graha, testBean:

Neispravna definicija graha s nazivom "testBean" ... 

A drugi nam pokazuje puni put zahvaćenih konfiguracija:

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

Kao rezultat, možemo vidjeti da su dva različita graha identificirana kao testBean izazivajući sukob. Uz to, grah se nalazi unutar klasa konfiguracije TestConfiguration1 i TestConfiguration2.

6. Moguća rješenja

Ovisno o našoj konfiguraciji, Spring Beans imaju zadana imena, osim ako ih eksplicitno ne postavimo.

Stoga je prvo moguće rješenje preimenovanje našeg graha.

Postoje neki uobičajeni načini postavljanja naziva graha u proljeće.

6.1. Promjena naziva metoda

Prema zadanim postavkama, Spring uzima ime označenih metoda kao nazive graha.

Stoga, ako imamo grah definiran u klasi konfiguracije, poput našeg primjera, tada će jednostavna promjena imena metoda spriječiti BeanDefinitionOverrideException:

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

6.2. @Grah Bilješka

Proljetni @Grah anotacija je vrlo čest način definiranja graha.

Stoga je druga mogućnost postaviti Ime vlasništvo @Grah napomena:

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

6.3. Bilješke stereotipa

Drugi način definiranja zrna je stereotipnim bilješkama. S Springovim @ComponentScan Omogućena značajka, možemo definirati nazive graha na razini klase pomoću @Komponenta napomena:

@Component ("testBean1") klasa TestBean1 {naziv privatnog niza; // standardni geteri i postavljači} 
@Component ("testBean2") klasa TestBean2 {naziv privatnog niza; // standardni geteri i postavljači} 

6.4. Grah koji dolazi iz knjižnica trećih strana

U nekim slučajevima, moguće je naići na sukob imena uzrokovan grahom koji potječe iz trećih strana proljetno podržanih knjižnica.

Kada se to dogodi, trebali bismo pokušati identificirati koji grah u sukobu pripada našoj aplikaciji, kako bismo utvrdili može li se upotrijebiti neko od gore navedenih rješenja.

Međutim, ako ne uspijemo izmijeniti nijednu definiciju graha, konfiguriranje Spring Boota kako bi se omogućilo nadjačavanje graha može biti rješenje.

Da bismo omogućili nadjačavanje graha, postavimo spring.main.allow-grah-definicija-nadjačavanje svojstvo da pravi u našem primjena.svojstva datoteka:

spring.main.allow-bean-definition-overriding = true 

Čineći to, poručujemo Spring Bootu da omogući nadjačavanje graha bez ikakvih promjena u definicijama graha.

Kao posljednju obavijest, toga bismo trebali biti svjesni teško je pogoditi koji će grah imati prioritet jer je redoslijed stvaranja graha određen odnosima ovisnosti na koje se najviše utječe u vrijeme izvođenja. Stoga, dopuštanje nadjačavanja graha može proizvesti neočekivano ponašanje ukoliko ne poznajemo dovoljno hijerarhiju ovisnosti naših graha.

7. Zaključak

U ovom uputstvu objasnili smo što BeanDefinitionOverrideException znači u proljeće, zašto se iznenada pojavljuje i kako ga riješiti nakon nadogradnje Spring Boot 2.1.

Kao i uvijek, cjelokupni izvorni kod ovog članka nalazi se na GitHubu.


$config[zx-auto] not found$config[zx-overlay] not found