知識庫 / Spring RSS 訂閱

Spring NoSuchBeanDefinitionException

Spring
HongKong
9
03:02 PM · Dec 06 ,2025

1. 概述

本教程將討論 Spring 中的 org.springframework.beans.factory.NoSuchBeanDefinitionException 異常。

該異常通常由 BeanFactory 在嘗試解析 Spring 上下文中 未定義 bean 時拋出。

我們將探討導致此問題可能的原因以及可用的解決方案。

當然,異常會在我們意想不到的時候發生,因此請查看 Spring 中所有異常和解決方案的完整列表。

2. 原因:未找到類型[…]的合格Bean作為依賴項導致此異常的最常見原因是嘗試注入未定義的Bean。

例如,BeanB 正在注入一個協作對象,BeanA:

@Component
public class BeanA {

    @Autowired
    private BeanB dependency;
    //...
}

如果依賴 BeanB 未在 Spring 上下文中定義,引導過程將因 “未找到該 bean 定義”異常 失敗:

org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type [com.baeldung.packageB.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)}

原因顯然由 Spring 明確指出:該依賴項至少應有 1 個符合自動注入候選者的 Bean

原因可能是 BeanB 在上下文中不存在——如果 Bean 通過 類路徑掃描 自動拾取,並且 BeanB 正確地被標註為 Bean(如 @Component@Repository@Service@Controller 等)——則它可能定義在 未被 Spring 掃描的包中

package com.baeldung.packageB;
@Component
public class BeanB { ...}

類路徑掃描可以配置如下:

@Configuration
@ComponentScan("com.baeldung.packageA")
public class ContextWithJavaConfig {
    ...
}

如果豆子沒有自動掃描,而是手動定義,那麼BeanB在當前Spring上下文中根本未定義。

3. 原因:字段 […] 在 […] 中需要一個類型為 […] 的 Bean,但該 Bean 無法找到

在上述場景中的 Spring Boot 應用程序中,我們收到了一條不同的消息。

讓我們以相同的示例為例,其中 BeanB 被連接到 BeanA,但它未定義:

@Component
public class BeanA {
	
    @Autowired
    private BeanB dependency;
    //...
}

如果我們嘗試運行這個簡單的應用程序,該應用程序試圖加載 BeanA:

@SpringBootApplication
public class NoSuchBeanDefinitionDemoApp {

    public static void main(String[] args) {
        SpringApplication.run(NoSuchBeanDefinitionDemoApp.class, args);
    }
}

應用程序將使用以下錯誤消息失敗:

***************************
APPLICATION FAILED TO START
***************************

Description:

Field dependency in com.baeldung.springbootmvc.nosuchbeandefinitionexception.BeanA required a bean of type 'com.baeldung.springbootmvc.nosuchbeandefinitionexception.BeanB' that could not be found.


Action:

Consider defining a bean of type 'com.baeldung.springbootmvc.nosuchbeandefinitionexception.BeanB' in your configuration.

以下是關於 com.baeldung.springbootmvc.nosuchbeandefinitionexception 包的信息,該包包含 BeanABeanBNoSuchBeanDefinitionDemoApp

4. 原因:未定義類型[…]的合格Bean

另一個導致該異常的原因是上下文中存在兩個Bean定義,而不是一個。

例如,接口 IBeanB 由兩個Bean BeanB1BeanB2 實現:

@Component
public class BeanB1 implements IBeanB {
    //
}
@Component
public class BeanB2 implements IBeanB {
    //
}

現在如果 BeanA 自動注入這個接口,Spring 將不會知道應該注入哪個實現:

@Component
public class BeanA {

    @Autowired
    private IBeanB dependency;
    ...
}

再次強調,這將會導致NoSuchBeanDefinitionExceptionBeanFactory拋出:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: 
No qualifying bean of type 
  [com.baeldung.packageB.IBeanB] is defined: 
expected single matching bean but found 2: beanB1,beanB2

同樣,Spring 明確指示了 Wiring 失敗的原因:預期只有一個匹配的 Bean,但找到了 2 個

然而,請注意,在這種情況下拋出的異常不是 NoSuchBeanDefinitionException,而是一個子類:NoUniqueBeanDefinitionException。這個新的異常在 Spring 3.2.1 中 引入的,正是為了區分沒有找到 Bean 定義和在上下文中找到多個定義的情況。

在此變更之前,異常是上述的。

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type [com.baeldung.packageB.IBeanB] is defined: 
expected single matching bean but found 2: beanB1,beanB2

解決此問題的一種方法是使用 @Qualifier 註解,明確指定我們想要注入的 Bean 的名稱。

@Component
public class BeanA {

    @Autowired
    @Qualifier("beanB2")
    private IBeanB dependency;
    ...
}

現在,Spring 已經擁有足夠的信息來決定注入哪個 Bean —— BeanB1BeanB2 ( BeanB2 的默認名稱是 beanB2)。

5. 原因:未定義 Bean […]

當 Spring 上下文中嘗試通過名稱請求未定義的 Bean 時,可能會拋出 <em>NoSuchBeanDefinitionException</em> 異常。

@Component
public class BeanA implements InitializingBean {

    @Autowired
    private ApplicationContext context;

    @Override
    public void afterPropertiesSet() {
        context.getBean("someBeanName");
    }
}

在這種情況下,不存在對“someBeanName”的 Bean 定義,導致以下異常:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No bean named 'someBeanName' is defined

再次,Spring 清楚地簡潔地表明瞭失敗的原因:未定義名為 X 的 Bean

6. 原因:代理 Bean

當上下文中某個 Bean 使用 JDK Dynamic Proxy 機制進行代理時,代理不會繼承目標 Bean (但它會實現相同的接口)。

由於此原因,如果 Bean 通過接口注入,則會正確地進行綁定。但是,如果 Bean 通過實際的類注入,Spring 將無法找到與類匹配的 Bean 定義,因為代理實際上並沒有擴展該類。

Bean 被代理的一個非常常見的原因是 Spring 的事務支持,即那些帶有 @Transactional 註解的 Bean。

例如,如果 ServiceA 注入 ServiceB,並且這兩個服務都具有事務支持,那麼 通過類定義注入 將不起作用:

@Service
@Transactional
public class ServiceA implements IServiceA{

    @Autowired
    private ServiceB serviceB;
    ...
}

@Service
@Transactional
public class ServiceB implements IServiceB{
    ...
}

同樣的兩個服務,這次正確地通過接口注入,也會沒問題:

@Service
@Transactional
public class ServiceA implements IServiceA{

    @Autowired
    private IServiceB serviceB;
    ...
}

@Service
@Transactional
public class ServiceB implements IServiceB{
    ...
}

7. 結論

本文討論了常見 NoSuchBeanDefinitionException 的可能原因,重點介紹瞭如何在實踐中解決這些異常。

最後,Spring 中所有異常及其解決方案的完整列表 值得您收藏。

發佈 評論

Some HTML is okay.