Jarná výnimka NoSuchBeanDefinitionException

1. Prehľad

V tomto článku diskutujeme o Jar org.springframework.beans.factory.NoSuchBeanDefinitionException - toto je bežná výnimka vyvolaná BeanFactory pri pokuse o vyriešenie fazuľa, ktorá jednoducho nie je definovaná v kontexte jari.

Ukážeme možné príčiny tohto problému a dostupné riešenia.

A samozrejme, výnimky sa stávajú, keď to najmenej čakáte; na jar sa pozrite na celý zoznam výnimiek a riešení.

2. Príčina: Pre závislosť sa nenašiel žiadny kvalifikačný znak typu […]

Najbežnejšou príčinou tejto výnimky je jednoducho pokus o injekciu fazule, ktorá nie je definovaná. Napríklad - BeanB zapojí spolupracovníka - BeanA:

@ Komponent verejná trieda BeanA {@Autowired súkromná závislosť BeanB; // ...}

Teraz, ak závislosť - BeanB - nie je definovaný v jarnom kontexte, bootstrap proces zlyhá s žiadna taká výnimka z definície fazule:

org.springframework.beans.factory.NoSuchBeanDefinitionException: Pre závislosť sa nenašiel žiadny kvalifikačný fazuľa typu [com.baeldung.packageB.BeanB]: očakáva sa minimálne 1 fazuľa, ktorá sa kvalifikuje ako kandidát autowire pre túto závislosť. Poznámky k závislosti: {@ org.springframework.beans.factory.annotation.Autowired (required = true)}

Dôvod jasne naznačuje jar: „očakáva sa minimálne 1 fazuľa, ktorá sa kvalifikuje ako kandidát autowire pre túto závislosť

Jeden dôvod BeanB nemusí v tomto kontexte existovať - ​​ak fazuľa vyberá automaticky skenovanie triedy, A keď BeanB je správne anotovaný ako fazuľa (@ Komponent, @Úložisko, @Služba, @ Kontrolór, atď.) - je, že to môže byť definované v balík, ktorý Spring neskenuje:

balíček com.baeldung.packageB; @ Komponent verejnej triedy BeanB {...}

Zatiaľ čo skenovanie cesty k triede je možné nakonfigurovať nasledovne:

@Configuration @ComponentScan ("com.baeldung.packageA") verejná trieda ContextWithJavaConfig {...}

Ak fazuľa nie je automaticky skenovaná podľa definované manuálnepotom BeanB v súčasnom jarnom kontexte jednoducho nie je definovaný.

3. Príčina: Pole […] v poli […] vyžadovalo fazuľu typu […], ktorú nebolo možné nájsť

V aplikácii Spring Boot pre vyššie uvedený scenár dostaneme inú správu.

Zoberme si rovnaký príklad, kde BeanB je zapojený v BeanA ale nie je to definované:

@ Komponent verejná trieda BeanA {@Autowired súkromná závislosť BeanB; // ...}

Ak sa pokúsime spustiť túto jednoduchú aplikáciu, ktorá sa pokúsi načítať BeanA:

@SpringBootApplication verejná trieda NoSuchBeanDefinitionDemoApp {public static void main (String [] args) {SpringApplication.run (NoSuchBeanDefinitionDemoApp.class, args); }}

Aplikáciu sa nepodarí spustiť s chybovým hlásením:

**************************** APLIKÁCIA SA SPUSTILA ******************* ******** Popis: Závislosť poľa v com.baeldung.springbootmvc.nosuchbeandefinitionexception.BeanA vyžadovala fazuľu typu 'com.baeldung.springbootmvc.nosuchbeandefinitionexception.BeanB', ktorú nemožno nájsť. Akcia: Zvážte vo svojej konfigurácii definíciu fazule typu „com.baeldung.springbootmvc.nosuchbeandefinitionexception.BeanB“.

Tu, com.baeldung.springbootmvc.nosuchbeandefinitionexception je balík pre BeanA, BeanB a NoSuchBeanDefinitionDemoApp.

Útržok tohto príkladu nájdete v tomto projekte Github.

4. Príčina: Nie je definovaný žiadny kvalifikačný znak typu […]

Ďalšou príčinou výnimky je existencia dvoch definícií fazule v kontexte, namiesto jednej. Napríklad, ak rozhranie - IBeanB je implementovaný dvoma fazuľami - BeanB1 a BeanB2:

@ Verejná trieda komponentu BeanB1 implementuje IBeanB {//} @ Verejná trieda komponentu BeanB2 implementuje IBeanB {//}

Teraz, ak BeanA autowires toto rozhranie, Spring nebude vedieť, ktorú z dvoch implementácií vložiť:

@ Komponent public class BeanA {@Autowired súkromná závislosť IBeanB; ...}

Výsledkom bude opäť a NoSuchBeanDefinitionException je vyhodený BeanFactory:

Spôsobené: org.springframework.beans.factory.NoUniqueBeanDefinitionException: Nie je definovaný žiadny kvalifikačný fazuľa typu [com.baeldung.packageB.IBeanB]: očakáva sa jedno vyhovujúca fazuľa, ale našla sa 2: beanB1, beanB2

Podobne Spring jasne naznačuje dôvod poruchy vedenia: „Očakávaný jeden zodpovedajúci fazuľa, ale našiel sa 2“.

Všimnite si však, že v takom prípade presná výnimka nie je hodená NoSuchBeanDefinitionException ale podtrieda - the NoUniqueBeanDefinitionException. Táto nová výnimka bola zavedená na jar 3.2.1, a to práve z tohto dôvodu - aby sa rozlíšila príčina, pri ktorej sa nenašla definícia fazule, a táto - v kontexte sa nachádza niekoľko definícií.

Pred touto zmenou bola vyššie uvedená výnimka:

Spôsobené: org.springframework.beans.factory.NoSuchBeanDefinitionException: Nie je definovaný žiadny kvalifikovaný fazuľa typu [com.baeldung.packageB.IBeanB]: očakáva sa, že sa zhoduje jedna fazuľa, ale našla sa 2: beanB1, beanB2

Jeden riešením tohto problému je použitie @Qualifier anotácia presne určiť názov fazule, ktorú chceme spojiť:

@Component public class BeanA {@Autowired @Qualifier ("beanB2") súkromná závislosť IBeanB; ...}

Teraz má jar dostatok informácií na to, aby sa rozhodlo, ktorej fazuľke podať injekciu - BeanB1 alebo BeanB2 (predvolený názov BeanB2 je beanB2).

5. Príčina: Nie je definovaný žiadny fazuľa s názvom [...]

A NoSuchBeanDefinitionException sa môže hodiť, aj keď fazuľa, ktorá nie je definovaná, je požadované podľa mena z jarného kontextu:

@ Komponenta verejná trieda BeanA implementuje InitializingBean {@Autowired súkromný kontext ApplicationContext; @Override public void afterPropertiesSet () {context.getBean ("someBeanName"); }}

V tomto prípade neexistuje definícia fazule pre názov „someBeanName“, čo vedie k nasledujúcej výnimke:

Spôsobené: org.springframework.beans.factory.NoSuchBeanDefinitionException: Nie je definovaná žiadna fazuľa s názvom „someBeanName“

Jar opäť jasne a výstižne naznačuje dôvod neúspechu: „Nie je definovaná žiadna fazuľa s názvom X“.

6. Príčina: Proxy fazuľa

Keď je fazuľa v kontexte proxyovaná pomocou mechanizmu JDK Dynamic Proxy, potom server proxy nerozšíri cieľový fazuľa (bude však implementovať rovnaké rozhrania).

Z tohto dôvodu, ak je fazuľa vložená rozhraním, bude správne zapojená. Ak je však fazuľa vložená skutočnou triedou, potom Spring nenájde definíciu fazule, ktorá by zodpovedala triede - pretože proxy server v skutočnosti rozšíriť triedu.

Veľmi častým dôvodom, prečo môže byť fazuľa splnomocnená, je Jarná transakčná podpora - a to fazuľa, ktorá je označená @ Transakčné.

Napríklad ak SlužbaA vstrekuje Služba B.a obe služby sú transakčné, vstrekovanie podľa definície triedy nebudem pracovať:

@Service @Transactional public class ServiceA implementuje IServiceA {@Autowired private ServiceB serviceB; ...} @Service @Transactional public class ServiceB implementuje IServiceB {...}

Rovnaké dve služby, tentokrát správne vstrekovanie rozhraním, bude ok:

@Service @Transactional public class ServiceA implementuje IServiceA {@Autowired private IServiceB serviceB; ...} @Service @Transactional public class ServiceB implementuje IServiceB {...}

7. Záver

V tomto výučbe sa diskutovalo o príkladoch možných príčin spoločného výskytu NoSuchBeanDefinitionException - so zameraním na to, ako tieto výnimky v praxi riešiť.

Implementáciu všetkých týchto príkladov výnimiek nájdete v projekte GitHub - jedná sa o projekt založený na Eclipse, takže by malo byť ľahké ho importovať a spustiť tak, ako je.

Nakoniec celý zoznam výnimiek a riešení na jar môže byť dobrým zdrojom na uloženie záložiek.


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