涉及 Bean 相关的异常说明:
- NoSuchBeanDefinitionException:Bean 不存在
- NoUniqueBeanDefinitionException:多个 Bean
- BeanInstantiationException:注册了无法实例化的 Bean
- BeanCreationException:Bean 的初始化过程报错,如 init 方法内报错
- BeanDefinitionStoreException:BeanFactory 遇到非法的 BeanDefinition,如 xml 路径不对
复现代码:
spring xml 配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean name="user1" class="constxiong.User"/>
<bean name="user2" class="constxiong.User"/>
</beans>
测试代码
/**
* 测试 Bean 生命周期内的异常
* @author ConstXiong
*/
@Configuration
public class Test {
public static void main(String[] args) throws InterruptedException {
ApplicationContext context = new ClassPathXmlApplicationContext("/META-INF/spring-bean-exception.xml");
//NoSuchBeanDefinitionException,Bean 不存在
exec(() -> context.getBean("user"));
Thread.sleep(100L);
//NoUniqueBeanDefinitionException,多个 Bean
exec(() -> context.getBean(User.class));
Thread.sleep(100L);
//BeanInstantiationException,注册了无法实例化的 Bean
exec(() -> {
AnnotationConfigApplicationContext annotionApplicationContext = new AnnotationConfigApplicationContext();
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClass(UserInterface.class);
annotionApplicationContext.registerBeanDefinition("userInter", beanDefinition);
annotionApplicationContext.refresh();
annotionApplicationContext.getBean("userInter");
});
Thread.sleep(100L);
//BeanCreationException,Bean 的初始化过程报错,这里是 init 方法内
exec(() -> {
AnnotationConfigApplicationContext annotionApplicationContext = new AnnotationConfigApplicationContext();
annotionApplicationContext.registerBeanDefinition("userImpl",
BeanDefinitionBuilder.rootBeanDefinition(UserImpl.class).setInitMethodName("init").getBeanDefinition());
annotionApplicationContext.refresh();
context.getBean("userImpl");
});
Thread.sleep(100L);
//BeanDefinitionStoreException,BeanFactory 遇到非法的 BeanDefinition,这里 xml 路径不对
exec(() -> {
ApplicationContext context1 = new ClassPathXmlApplicationContext("/META-INF/spring-bean-exception1.xml");
context1.getBean("user1");
});
}
private static void exec(Runnable r) {
new Thread(r).start();
}
}
打印结果
Exception in thread "Thread-1" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'user' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:805)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1278)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:297)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1108)
at constxiong.Test.lambda$main$0(Test.java:20)
at java.lang.Thread.run(Thread.java:748)
Exception in thread "Thread-2" org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'constxiong.User' available: expected single matching bean but found 2: user1,user2
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1180)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveBean(DefaultListableBeanFactory.java:416)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:349)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1126)
at constxiong.Test.lambda$main$1(Test.java:24)
at java.lang.Thread.run(Thread.java:748)
二月 04, 2021 2:13:50 下午 org.springframework.context.support.AbstractApplicationContext refresh
警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userInter': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [constxiong.UserInterface]: Specified class is an interface
Exception in thread "Thread-3" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userInter': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [constxiong.UserInterface]: Specified class is an interface
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1320)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1214)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:879)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
at constxiong.Test.lambda$main$2(Test.java:33)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [constxiong.UserInterface]: Specified class is an interface
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:70)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1312)
... 12 more
二月 04, 2021 2:13:50 下午 org.springframework.context.support.AbstractApplicationContext refresh
警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userImpl': Invocation of init method failed; nested exception is java.lang.ArithmeticException: / by zero
Exception in thread "Thread-4" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userImpl': Invocation of init method failed; nested exception is java.lang.ArithmeticException: / by zero
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:879)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
at constxiong.Test.lambda$main$3(Test.java:43)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ArithmeticException: / by zero
at constxiong.UserImpl.init(UserImpl.java:6)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1922)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1864)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1792)
... 11 more
Exception in thread "Thread-5" org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [META-INF/spring-bean-exception1.xml]; nested exception is java.io.FileNotFoundException: class path resource [META-INF/spring-bean-exception1.xml] cannot be opened because it does not exist
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:345)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:305)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:188)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:224)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:195)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:257)
at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:128)
at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:94)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:133)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:637)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:522)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:144)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:85)
at constxiong.Test.lambda$main$4(Test.java:50)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.FileNotFoundException: class path resource [META-INF/spring-bean-exception1.xml] cannot be opened because it does not exist
at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:180)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:331)
... 14 more
完整代码:016-spring-bean-exception
【Java学习资源】整理推荐
- 自定义 Bean 作用域
- Bean 的作用域
- maven 集成 tomcat 以 jar 的方式打包 web 应用
- Spring 依赖注入与依赖查找来源的区别
- Spring 依赖注入的处理过程与 DependencyDescriptor 的说明
- Spring 各种 Aware 接口回调注入
- Spring Bean 生命周期内的 Exception 复现
- Spring 内建 Bean
- Spring Bean 的别名
- Spring Bean 未指定名称的命名规则
- Bean 何时被 GC
- Spring Bean 延迟加载
- ObjectFactory 与 BeanFactory 的区别
- Bean 销毁的方式与顺序
- Bean 初始化的方式与顺序
- Bean 的实例化方式
- Bean的注册方式
- 什么是 BeanDefinition?
- Spring IoC 容器启动时做了什么?
- BeanFactory 与 FactoryBean 的区别
- BeanFactory 与 ApplicationContext 的区别
- Spring IoC 依赖注入的实现方式
- Spring IoC 依赖注入(支持哪些数据类型?)
- Spring bean 依赖查找
- Spring-IoC
- Spring 的核心特性