环境:SpringBoot3.2.5
在篇文章,我们将详细讨论 BeanCreationException 异常。这是 BeanFactory 在创建定义的 Bean 时遇到问题时抛出的一种非常常见的异常。本文将探讨导致这种异常的最常见原因以及解决方案。
该异常的原因是 Spring 尝试注入一个容器中不存在的 Bean,如下示例:
public class UserDAO {}@Servicepublic class UserService { @Resource private UserDAO dao ;}
这里UserDAO类上并没有添加任何注解,当启动容器时,抛出如下错误
图片
遇到该异常,那你就要检查UserDAO类上是否添加了@Component, @Repository, @Service, @Controller, 这些注解(或者配置类中使用@Bean)。还有一点是,当前这个类所在的包在当前扫描的范围内。
该异常的原因是 Spring 在注入某个抽象类(接口)时,发现容器中存在多个,如下示例:
public interface DAO {}@Componentpublic class CommonDAO implements DAO {}@Componentpublic class PersonDAO implements DAO {}@Servicepublic class UserService { @Resource private DAO dao ;}
启动容器后,抛出如下错误
图片
解决办法就是指定名称,上面使用的@Resource可以指定name属性
@Servicepublic class UserService { @Resource(name = "personDAO") private DAO dao ;}
如果你使用的@Autowired,那么你可以使用@Qualifier
出现该异常的原因是在创建实例对象时,如下示例:
@Controllerpublic class UserController { public UserController() { // TODO throw new RuntimeException("异常了") ; }}
在构造函数中,执行相关的操作时,抛出了异常,错误信息如下:
图片
抽象类定义为Bean
@Controllerpublic abstract class UserController { public UserController() { }}
抛出错误如下:
图片
根据异常信息提示,已经告诉你是否是抽象类。
如果一个 Bean 没有默认构造函数(无参的),而是定义了有参的构造函数,那么如果容器中不存在参数类型的bean,那么会抛出该异常,如下示例:
@Componentpublic class User { public User(String name) { System.out.println(name) ; }}
抛出异常
图片
检查容器中是否有一个String类型的Bean对象。
该异常出现的概率非常小,因为我们现在都是基于注解的方式去配置bean,很少使用xml方式,除了xml方式为,我们还可以通过注册BeanDefinition方式来来注册Bean,接下来我们通过注册BeanDefinition方式来设置bean的相关属性,如下示例:
public class UserService { private DAO dao ;}
该类并没有对dao属性定义setter方法。接下来,通过如下方式注册上面的Bean对象:
ConfigurableApplicationContext context = ...context.registerBean("userService", UserService.class, bd -> { bd.getPropertyValues().add("dao", xxx) ;}) ;
通过BeanDefinition方式注册bean,并添加属性,运行程序后抛出如下错误:
图片
该异常通常发生在使用构造器注入时,例如循环依赖的情况下,如下示例:
@Componentpublic class A { public A(B b) {}}@Componentpublic class B { public B(A a) { }}
抛出如下错误
异常信息中已经描述了,是否是循环依赖,解决改异常,可以在任意一方使用@Lazy注解即可,如下示例:
public class A { public A(@Lazy B b) {}}
这里只需要在任何一方的参数上添加@Lazy注解即可解决该循环依赖问题。
当容器中出现beanName相同的情况(不允许覆盖),则抛出该异常,如下示例:
@Component("xxxooo")public class A {}@Component("xxxooo")public class B {}
这里定义了2个beanName都为xxxooo的对象,默认情况下,springboot是不允许覆盖的,如下属性配置:
spring: main: allow-bean-definition-overriding: false
在这种情况下,启动时将抛出如下错误:
图片
当设置为true,以后,容器中将存在的将是xxxooo=com.pack.B。后面的会覆盖前面定义的bean。
本文链接:http://www.28at.com/showinfo-26-112783-0.htmlSpringBoot这些异常你知道原因吗?你遇过到几个?
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com
下一篇: 这应该是全网最详细的Vue3.5版本解读