Spring Bean 生命周期内的 Exception 复现

涉及 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学习资源】整理推荐

 

 


【Java面试题与答案】整理推荐

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值