知識庫 / Spring RSS 訂閱

Spring BeanDefinitionStoreException

Spring
HongKong
5
03:12 PM · Dec 06 ,2025

1. 概述

本文將討論 Spring 中的 <em><strong>org.springframework.beans.factory.BeanDefinitionStoreException</strong></em> – 當 Bean 定義無效時,這通常由 <em>BeanFactory</em> 負責。加載該 Bean 存在問題。本文將討論該異常的最常見原因以及每個解決方案。

2. 原因:java.io.FileNotFoundException

BeanDefinitionStoreException 可能是由潛在的 IOException 引起的,可能導致以下情況:

2.1. 從 ServletContext 資源解析 IOException

這通常發生在 Spring Web 應用程序中,當 DispatcherServlet 被在 web.xml 中配置為 Spring MVC 的一部分時:

<servlet>  
   <servlet-name>mvc</servlet-name>  
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
</servlet>

默認情況下,Spring 會在 Web 應用程序的 WEB-INF</em/> 目錄下查找名為 springMvcServlet-servlet.xml</em/> 的文件。

如果該文件不存在,則會拋出以下異常:

org.springframework.beans.factory.BeanDefinitionStoreException: 
Ioexception Parsing Xml Document from Servletcontext Resource [/WEB-INF/mvc-servlet.xml]; 
nested exception is java.io.FileNotFoundException: 
Could not open ServletContext resource [/WEB-INF/mvc-servlet.xml]

解決方案當然是確保 mvc-servlet.xml 文件確實存在於 /WEB-INF 下;如果不存在,則可以創建一個示例文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans 
   xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
      http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-3.2.xsd" >

</beans>

2.2. 從類路徑資源解析 XML 文檔時出現 IOException

這通常發生在應用程序中的某個地方指向不存在或未放置在正確位置的 XML 資源時。

指向此類資源的可能方式多種多樣。

例如,使用 Java 配置,它可能如下所示:

@Configuration
@ImportResource("beans.xml")
public class SpringConfig {...}

在XML中,將會是:

<import resource="beans.xml"/>

或者通過手動創建 Spring XML 配置文件:

ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

所有這些都將在文件不存在時導致相同的異常:

org.springframework.beans.factory.BeanDefinitionStoreException: 
Ioexception Parsing Xml Document from Servletcontext Resource [/beans.xml]; 
nested exception is java.io.FileNotFoundException: 
Could not open ServletContext resource [/beans.xml]

解決方案是創建文件並將其放置在項目/src/main/resources目錄下, 這樣文件就會存在於類路徑上,並被 Spring 找到並使用。

3. 原因:無法解析佔位符

此錯誤發生在Spring嘗試解析屬性時,由於多種可能原因,未能成功解析。

不過,首先需要了解屬性的使用方式——這可能在XML中使用:

... value="${some.property}" ...

該屬性也可以在 Java 代碼中使用:

@Value("${some.property}")
private String someProperty;

首先需要檢查的是,屬性的名稱是否與屬性定義相符;在本例中,我們需要定義以下屬性:

some.property=someValue

然後,我們需要檢查 Spring 中屬性文件的定義 – 這在我的 Spring 中屬性文件教程中進行了詳細説明。 遵循的最佳實踐是所有屬性文件都位於應用程序的 /src/main/resources 目錄下,並通過以下方式加載:

"classpath:app.properties"

繼續討論一下顯而易見的原因——Spring 無法解析屬性的另一個可能原因在於 Spring 上下文中可能存在多個 PropertyPlaceholderConfigurer Bean,或者多個 property-placeholder 元素。

如果是這種情況,解決方案是將其合併為一個,或者在父上下文配置中使用 ignoreUnresolvablePlaceholders

4. 原因:java.lang.NoSuchMethodError

這個錯誤表現形式多種多樣,其中一種比較常見的情況是:

org.springframework.beans.factory.BeanDefinitionStoreException:
Unexpected exception parsing XML document from ServletContext resource [/WEB-INF/mvc-servlet.xml];
nested exception is java.lang.NoSuchMethodError:
org.springframework.beans.MutablePropertyValues.add (Ljava/lang/String;Ljava/lang/Object;)
Lorg/springframework/beans/MutablePropertyValues;

這通常發生在 classpath 上存在多個 Spring 版本時。意外地在項目 classpath 上存在較舊版本的 Spring 比人們想象的要常見得多——我在 Spring Security with Maven 文章中描述了問題和解決方案。

簡而言之,解決此錯誤的方法很簡單——檢查 classpath 上所有 Spring 罐子,並確保它們都具有相同的版本——該版本必須為 3.0 或更高版本。

同樣,該異常並不限於 MutablePropertyValues bean——還有其他多個變體,由相同的版本不一致性引起:

org.springframework.beans.factory.BeanDefinitionStoreException:
Unexpected exception parsing XML document from class path resource [/WEB-INF/mvc-servlet.xml];
- nested exception is java.lang.NoSuchMethodError:
org.springframework.util.ReflectionUtils.makeAccessible(Ljava/lang/reflect/Constructor;)V

5. 原因:java.lang.NoClassDefFoundError

一個常見問題,與 Maven 和現有 Spring 依賴關係類似是:

org.springframework.beans.factory.BeanDefinitionStoreException:
Unexpected exception parsing XML document from ServletContext resource [/WEB-INF/mvc-servlet.xml];
nested exception is java.lang.NoClassDefFoundError: 
org/springframework/transaction/interceptor/TransactionInterceptor

當交易功能在 XML 配置中配置時,會發生這種情況。

<tx:annotation-driven/>

NoClassDefFoundError 表示 Spring 事務支持——即 spring-tx ——未在類路徑上定義。

解決方案很簡單——需要將 spring-tx 添加到 Maven pom 中。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>4.1.0.RELEASE</version>
</dependency>

當然,這不僅僅限於交易功能——如果AOP 缺失時也會拋出類似的錯誤:

Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: 
Unexpected exception parsing XML document from class path resource [/WEB-INF/mvc-servlet.xml]; 
nested exception is java.lang.NoClassDefFoundError: 
org/aopalliance/aop/Advice

現在所需的 jar 包如下:spring-aop (以及隱含的 aopalliance):

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>4.1.0.RELEASE</version>
</dependency>

6. 結論

在本文結束時,我們應該對可能導致 Bean 定義存儲異常 的各種原因和問題有一個清晰的路線圖,並且對如何解決這些問題也有了充分的理解。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.