環境: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.tebozhan.com/showinfo-26-112783-0.htmlSpringBoot這些異常你知道原因嗎?你遇過到幾個?
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
下一篇: 這應該是全網最詳細的Vue3.5版本解讀