Abstract: This article is translated from Eugen Paraschiv article Spring nosuchbeandefinitionexception original link: http://www.baeldung.com/ Spring-nosuchbeandefinitionexception thanked Eugen Paraschiv for doing the research.
Overview
In this article, I'll show you the reasons for org.springframework.beans.factory.NoSuchBeanDefinitionException in spring with an example. This common exception is thrown if Beanfactory does not find an instance of the bean in spring context.
Cause:no qualifying Bean of type [...] found for dependency
This exception occurs generally because the bean that needs to be injected is undefined
There is a class of Beana.java
package com.csdn.training.model;@Componentpublic class BeanA { @Autowired private BeanB beanB;}
There is a class of Beanb.java
package com.csdn.training.service;@Componentpublic class BeanB {}
Configuration file Applicationcontext.xml
<context:component-scan base-package="com.csdn.training.model"></context:component-scan>
Use a test class to start pulling up the spring container:
package com.csdn.test;public class AppTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); BeanA beanA = (BeanA) context.getBean("beanA"); }}
Auto Scan package path missing BEANB, it is not in the same path as Beana
If the dependent ibusinessservice is not defined in the spring context, the boot process error: No Such Bean definition Exception.
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.csdn.training.service.BeanB] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.
Spring will prompt: "expected at least 1 beans which qualifies as Autowire candidatefor this dependency" (dependent on at least one alternative bean can be automatically Injection
The exception occurs because the Ibusinessservice does not exist in the context: if the bean is assembled by classpath automatic scanning, and Ibusinessservice has been correctly annotated (@Component, @Repository , @Service, @Controller, etc.), maybe you didn't tell spring the correct package path.
Configuration files can be configured as follows:
<context:component-scan base-package="com.csdn.training"></context:component-scan>
If the bean cannot be scanned automatically and the manual definition is recognized, the bean is not defined in the spring context.
Cause:no qualifying Bean of type [...] is defined
This exception can be caused by the existence of two or more definitions of the bean in the spring context. If the interface IService has two implementation classes Serviceimpla and SERVICEIMPLB
Interface: Iservice.java
package com.csdn.training.service;public interface IService {}
Two implementation classes: Serviceimpla.java
package com.csdn.training.service;import org.springframework.stereotype.Service;@Servicepublic class ServiceImplA implements IService {}
Serviceimplb.java
package com.csdn.training.service;import org.springframework.stereotype.Service;@Servicepublic class ServiceImplB implements IService {}
If Beana automatically injects this interface, spring will not be able to tell which implementation class to inject:
package com.csdn.training.model;import com.csdn.training.service.IService;@Componentpublic class BeanA { @Autowired private IService serviceImpl;}
Then, Beanfactory throws an exception nosuchbeandefinitionexception
Spring will prompt: "expected single matching beans but found 2" (should match only one bean but found multiple)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.csdn.training.service.IService] is defined: expected single matching bean but found 2: serviceImplA,serviceImplB
In the example above, sometimes you see the exception information is nouniquebeandefinitionexception, it is nosuchbeandefinitionexception its subclass, in spring 3.2.1, fixed this exception, To distinguish this exception from the Bean's undefined.
nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.csdn.training.service.IService] is defined: expected single matching bean but found 2: serviceImplA,serviceImplB
To resolve this exception, you can use the annotation @qualifier to specify the name of the bean you want to inject.
package com.csdn.training.model;import com.csdn.training.service.IService;@Componentpublic class BeanA { @Autowired @Qualifier("serviceImplA") private IService serviceImpl;}
Once modified, spring can distinguish between the instances that should be injected into that bean, and note that the default instance name of Serviceimpla is Serviceimpla
Cause:no Bean Named [...] is defined
When you get an instance of a bean by the name of a specific bean, this exception is thrown if spring does not find the bean in the context.
package com.csdn.test;public class AppTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); context.getBean("beanX"); }}
In this example, no bean is defined as "Beanx", and the following exception is thrown:
Spring will prompt: "no bean named XXX is defined" (not found a bean named XXX)
‘beanX‘ is defined at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition
Cause:proxied Beans
If the bean is managed by the dynamic agent mechanism of the JDK, then the agent will not inherit the bean, it will only implement the same interface as the one. Therefore, if the bean is injected through an interface, it can be injected successfully. If you implement class injection through it, spring cannot associate a bean instance with a class because the proxy does not really inherit from the class.
This is probably because you used the spring thing and used annotations on the bean @transactional
as follows, ServiceA injects ServiceB, and the two service uses things, and injecting beans by implementing a class does not work.
Excuses Iservice.java no change, its implementation class plus the annotations of Things
Serviceimpla.java
package com.csdn.training.service;@Service@Transactionalpublic class ServiceImplA implements IService { @Autowired private ServiceImplB serviceImplB;}
Serviceimplb.java
package com.csdn.training.service;@Service@Transactionalpublic class ServiceImplB implements IService {}
If you change to inject via an interface, you can:
Serviceimpl.java
package com.csdn.training.service;@Service@Transactionalpublic class ServiceImplA implements IService { @Autowired @Qualifier("serviceImplB") private IService serviceImplB;}
Conclusion
Through several small examples, this paper analyzes the possible situations of nosuchbeandefinitionexception using this anomaly, and provides some references for us to locate errors in the actual development process.
The original English version, I made a slight change on the basis of the original text, but try to keep the essence of the original text, if there is objection to the translation, please correct me.
Reason analysis of "turn" Spring nosuchbeandefinitionexception