1. Información general
En este artículo, estamos discutiendo la excepción Spring org.springframework.beans.factory.BeanCreationException : esta es una excepción muy común que se produce cuando BeanFactory crea beans de las definiciones de bean y encuentra un problema. El artículo discutirá las causas más comunes de esta excepción junto con la solución.
2. Causa: org.springframework.beans.factory.NoSuchBeanDefinitionException
Con mucho, la causa más común de la BeanCreationException es que Spring intenta inyectar un bean que no existe en el contexto.
Por ejemplo, BeanA está intentando inyectar BeanB :
@Component public class BeanA { @Autowired private BeanB dependency; ... }
Si no se encuentra un BeanB en el contexto, se lanzará la siguiente excepción (Error al crear el Bean):
Error creating bean with name 'beanA': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.baeldung.web.BeanB cpm.baeldung.web.BeanA.dependency; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.baeldung.web.BeanB] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Para diagnosticar este tipo de problema, primero asegúrese de que el bean esté declarado:
- ya sea en un archivo de configuración XML utilizando el elemento
- o en una clase Java @Configuration a través de la anotación @Bean
- o está anotado con: @Component , @Repository , @Service , @Controller y el escaneo de classpath está activo para ese paquete
También verifique que los archivos o clases de configuración sean realmente recogidos por Spring y cargados en el contexto principal.
3. Causa: org.springframework.beans.factory.NoUniqueBeanDefinitionException
Otra causa similar para la excepción de creación de beans es que Spring intenta inyectar un bean por tipo, es decir, por su interfaz, y encuentra dos o más beans que implementan esa interfaz en el contexto.
Por ejemplo, BeanB1 y BeanB2 implementan la misma interfaz:
@Component public class BeanB1 implements IBeanB { ... } @Component public class BeanB2 implements IBeanB { ... } @Component public class BeanA { @Autowired private IBeanB dependency; ... }
Esto dará lugar a la siguiente excepción lanzada por la fábrica de frijoles Spring:
Error creating bean with name 'beanA': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.baeldung.web.IBeanB com.baeldung.web.BeanA.b; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.baeldung.web.IBeanB] is defined: expected single matching bean but found 2: beanB1,beanB2
4. Causa: org.springframework.beans.BeanInstantiationException
4.1. Excepción personalizada
El siguiente en la línea es un bean que lanza una excepción durante su proceso de creación ; una muestra simplificada para ejemplificar y comprender fácilmente el problema es lanzar una excepción en el constructor del bean:
@Component public class BeanA { public BeanA() { super(); throw new NullPointerException(); } ... }
Como era de esperar, esto provocará que Spring falle rápidamente con la siguiente excepción:
Error creating bean with name 'beanA' defined in file [...BeanA.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.baeldung.web.BeanA]: Constructor threw exception; nested exception is java.lang.NullPointerException
4.2. java.lang.InstantiationException
Otra posible aparición de la BeanInstantiationException es definir una clase abstracta como un bean en XML; esto tiene que estar en XML, porque no hay forma de hacer esto en un archivo de configuración de Java y el escaneo de classpath ignorará la clase abstracta:
@Component public abstract class BeanA implements IBeanA { ... }
Y la definición XML del bean:
Esta configuración resultará en una excepción similar:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'beanA' defined in class path resource [beansInXml.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.baeldung.web.BeanA]: Is it an abstract class?; nested exception is java.lang.InstantiationException
4.3. java.lang.NoSuchMethodException
Si un bean no tiene un constructor predeterminado y Spring intenta instanciarlo buscando ese constructor, esto resultará en una excepción de tiempo de ejecución; por ejemplo:
@Component public class BeanA implements IBeanA { public BeanA(final String name) { super(); System.out.println(name); } }
Cuando este bean es recogido por el mecanismo de escaneo de classpath, el error será:
Error creating bean with name 'beanA' defined in file [...BeanA.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.baeldung.web.BeanA]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.baeldung.web.BeanA.()
Una excepción similar, pero más difícil de diagnosticar, puede ocurrir cuando las dependencias de Spring en la ruta de clases no tienen la misma versión ; este tipo de incompatibilidad de versiones puede resultar en una NoSuchMethodException debido a cambios en la API. La solución a este problema es asegurarse de que todas las bibliotecas de Spring tengan exactamente la misma versión en el proyecto.
5. Causa: org.springframework.beans.NotWritablePropertyException
Otra posibilidad más es definir un bean - BeanA - con una referencia a otro bean - BeanB - sin tener el método setter correspondiente en BeanA :
@Component public class BeanA { private IBeanB dependency; ... } @Component public class BeanB implements IBeanB { ... }
Y la configuración de Spring XML:
Nuevamente, esto solo puede ocurrir en la configuración XML , porque cuando se usa Java @Configuration , el compilador hará que este problema sea imposible de reproducir.
Por supuesto, para resolver este problema, es necesario agregar el configurador para IBeanB :
@Component public class BeanA { private IBeanB dependency; public void setDependency(final IBeanB dependency) { this.dependency = dependency; } }
6. Causa: org.springframework.beans.factory.CannotLoadBeanClassException
This exception is thrown when Spring cannot load the class of the defined bean – this may occur if the Spring XML Configuration contains a bean that simply doesn't have a corresponding class. For example, if class BeanZ doesn't exist, the following definition will result in an exception:
The root cause if the ClassNotFoundException and the full exception in this case is:
nested exception is org.springframework.beans.factory.BeanCreationException: ... nested exception is org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [com.baeldung.web.BeanZ] for bean with name 'beanZ' defined in class path resource [beansInXml.xml]; nested exception is java.lang.ClassNotFoundException: com.baeldung.web.BeanZ
7. Children of BeanCreationException
7.1. The org.springframework.beans.factory.BeanCurrentlyInCreationException
One of the subclasses of BeanCreationException is the BeanCurrentlyInCreationException; this usually occurs when using constructor injection – for example, in a case of circular dependencies:
@Component public class BeanA implements IBeanA { private IBeanB beanB; @Autowired public BeanA(final IBeanB beanB) { super(); this.beanB = beanB; } } @Component public class BeanB implements IBeanB { final IBeanA beanA; @Autowired public BeanB(final IBeanA beanA) { super(); this.beanA = beanA; } }
Spring will not be able to resolve this kind of wiring scenario and the end result will be:
org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?
The full exception is very verbose:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'beanA' defined in file [...BeanA.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [com.baeldung.web.IBeanB]: : Error creating bean with name 'beanB' defined in file [...BeanB.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [com.baeldung.web.IBeanA]: : Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'beanB' defined in file [...BeanB.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [com.baeldung.web.IBeanA]: : Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?
7.2. The org.springframework.beans.factory.BeanIsAbstractException
This instantiation exception may occur when the Bean Factory attempts to retrieve and instantiate a bean which was declared as abstract; for example:
public abstract class BeanA implements IBeanA { ... }
Declared in the XML Configuration as:
Now, if we try to retrieve BeanA from the Spring Context by name – for example when instantiating another bean:
@Configuration public class Config { @Autowired BeanFactory beanFactory; @Bean public BeanB beanB() { beanFactory.getBean("beanA"); return new BeanB(); } }
This will result in the following exception:
org.springframework.beans.factory.BeanIsAbstractException: Error creating bean with name 'beanA': Bean definition is abstract
Y el stacktrace de excepción completo:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'beanB' defined in class path resource [org/baeldung/spring/config/WebConfig.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public com.baeldung.web.BeanB com.baeldung.spring.config.WebConfig.beanB()] threw exception; nested exception is org.springframework.beans.factory.BeanIsAbstractException: Error creating bean with name 'beanA': Bean definition is abstract
8. Conclusión
Al final de este artículo, deberíamos tener un mapa claro para navegar por la variedad de causas y problemas que pueden llevar a una BeanCreationException en Spring, así como una buena idea de cómo solucionar todos estos problemas.
La implementación de todos los ejemplos de excepciones se puede encontrar en el proyecto github; este es un proyecto basado en Eclipse, por lo que debería ser fácil de importar y ejecutar como está.