Spring 确实存在时找不到 bean xml 配置文件

Posted

技术标签:

【中文标题】Spring 确实存在时找不到 bean xml 配置文件【英文标题】:Spring cannot find bean xml configuration file when it does exist 【发布时间】:2012-10-05 07:36:24 【问题描述】:

我正在尝试在 Spring 中制作我的第一个 bean,但在加载上下文时遇到了问题。 我在 src/main/resources 中有一个 bean 的配置 XML 文件。

我收到以下 IOException:

线程“main”中的异常 org.springframework.beans.factory.BeanDefinitionStoreException:IOException 从类路径资源 [src/main/resources/beans.xml] 解析 XML 文档;嵌套异常是

java.io.FileNotFoundException: 类路径资源 [src/main/resources/beans.xml] 不能 因为不存在所以打开

但我不明白,因为我做了以下代码测试:

File f = new File("src/main/resources/beans.xml");
System.out.println("Exist test: " + f.exists());

这给了我真实的! resources 在类路径中。怎么了?

【问题讨论】:

如何加载上下文? 【参考方案1】:

我怀疑您正在构建一个 .war/.jar,因此它不再是一个文件,而是该包中的一个资源。请改用ClassLoader.getResourceAsStream(String path)。

【讨论】:

嗨... 抱歉问的有点晚了,您能否详细说明如何从输入流转换为应用程序上下文?我目前正在尝试运行一个可执行的 jar 文件,但它说它无法加载 bean xml,因为它不存在。【参考方案2】:

您已经查看了 src 目录。 xml 文件确实存在那里。但是请查看设置了所有输出类的类或 bin/build 目录。我怀疑您只需要使用 resources/beans.xml 路径。

【讨论】:

【参考方案3】:

谢谢,但这不是解决方案。我发现它为什么不适合我。

既然我做了一个声明:

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

当 beans.xml 文件存在时,我想我会参考项目的根目录。 然后我把配置文件放到 src/main/resources 里面,把初始化改成:

ApplicationContext context = new ClassPathXmlApplicationContext("src/main/resources/beans.xml");

它仍然是一个 IO 异常。

然后文件留在 src/main/resources/ 但我将声明更改为:

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

它解决了问题 - 也许它会对某人有所帮助。

感谢和欢呼!

编辑:

由于我的解决方案得到了很多人的赞许,并且几年前还是学生时第一次体验了 Spring,所以我很想尽快解释一下它为什么有效。

当项目被编译和打包时,项目中'src/main/java'中的所有文件和子目录都会进入打包的jar(我们要创建的工件)的根目录。相同的规则适用于“src/main/resources”。

这是许多工具(如 maven 或 sbt)在构建项目过程中所遵循的约定(注意:作为默认配置!)。当代码(来自帖子)处于运行模式时,它找不到像“src/main/resources/beans.xml”这样的东西,因为 beans.xml 位于 jar 的根目录中(复制到 /beans .xml 在创建的 jar/ear/war 中)。

当使用 ClassPathXmlApplicationContext 时,bean xml 定义的正确位置声明(在这种情况下)是“/beans.xml”,因为这是它在 jar 中以及稍后在类路径中所属的路径。

可以通过使用存档器(即 rar)解压 jar 并通过目录结构查看其内容来验证。

我建议阅读有关类路径的文章作为补充。

【讨论】:

我看不出ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");之间的区别 @FlorianF 没有区别。不同之处在于文件的放置位置,帖子中描述的内容。 我看到你将beans.xml 更改为src/main/resources/beans.xml,然后返回 更改为beans.xml。谢谢。 你不应该在类路径上有 src 。当您构建项目时,这些资源将被打包到其他地方。 嗨,如果我们从命令行运行这个 jar,它似乎没有按预期工作(在 eclipse 上工作正常)。【参考方案4】:

试试这个:

new ClassPathXmlApplicationContext("<b>file:</b>src/main/resources/beans.xml");

file: 前缀指向文件系统资源,而不是类路径。

文件路径可以是相对路径或系统路径(/home/user/Work/src...)

【讨论】:

好吧,将资源保存在类路径中比硬编码更好,但是谢谢。那个时候我没接触过CP :-) 对文件使用FileSystemXmlApplicationContext 可能会更好。 我有类似的问题,这个解决方案对我有用。【参考方案5】:

我也遇到了类似的问题,但由于原因有点不同,所以在这里分享一下,以防它可以帮助任何人。

我的文件位置

我是如何使用的

ClassPathXmlApplicationContext("beans.xml");

有两种解决方案

    将 beans.xml 从包中取出并放入默认包中。 在使用时指定包名称,即。

ClassPathXmlApplicationContext("com/mypackage/beans.xml");

【讨论】:

好吧,说得对。参考“com/mypackage/beans.xml”与“/com/mypackage/beans.xml”相同,因为“com/mypackage/beans.xml”是使用“/”(根)构建绝对路径的相关路径。 【参考方案6】:

我做了与大多数人相反的事情。我正在使用 Force IDE Luna Java EE,并将 Beans.xml 文件放在包中;但是,我在 Beans.xml 字符串(用于 ClassPathXMLApplicationContext 参数)之前加上了相对路径。所以在我的主应用程序中 - 访问 Beans.xml 文件的应用程序 - 我有:

    ApplicationContext context = 
         new ClassPathXmlApplicationContext("com/tutorialspoin/Beans.xml");

我还注意到,当我将 Beans.xml 文件从 src 文件夹移动到包中时,XML 文件图标的左下角有一个 Bean 图像,当这个 xml 文件在外面时不存在包裹。这是一个很好的指标,让我知道现在 ClassPathXMLAppllicationsContext 可以访问 beans xml 文件。

【讨论】:

【参考方案7】:

使用它 ApplicationContext context = new FileSystemXmlApplicationContext("Beans.xml");

【讨论】:

【参考方案8】:

这对我有用:

  new ClassPathXmlApplicationContext("classpath:beans.xml");

【讨论】:

嗨,这对我也有用,但问题是当构建 jar 文件时,jar 没有为我运行..我的意思是,我在尝试运行 jar 文件时收到 NoClassDefFoundError ,当我在 Eclipse 中作为 Java 运行应用程序时,它运行时没有错误,不知道如何解决这个问题【参考方案9】:

请注意,第一个 applicationContext 是作为 web.xml 的一部分加载的;下面会提到。

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>META-INF/spring/applicationContext.xml</param-value>
</context-param>

<servlet>
    <servlet-name>myOwn-controller</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>META-INF/spring/applicationContext.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

下面的代码也会尝试再创建一个applicationContext。

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

查看beans.xmlapplicationContext.xml之间的difference

如果&lt;META-INF/spring/&gt; 下的appliationContext.xml 已声明为&lt;import resource="beans.xml"/&gt;,则此appliationContext.xml 将在appliationContext.xml 的同一位置META-INF/spring 下加载beans.xml

在哪里;在代码中;如果它声明如下

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

这是在 WEB-INF/classes 或 eclipse 中查看 beans.xml src/main/resources

[如果您在src/main/resources 添加了beans.xml,那么它可能会在创建WAR 时放置在WEB-INF/classes。]

所以总共查找了两个文件。

我已经通过在applicationContext.xml 导入时添加类路径查找解决了这个问题,如下所示

<import resource="classpath*:beans.xml" />

并去掉java代码中ClassPathXmlApplicationContext("beans.xml")这一行,这样就只加载了一个ApplicationContext。

【讨论】:

【参考方案10】:

src/main/resources 是一个源目录,你不应该直接引用它。当您构建/打包项目时,内容将被复制到您的类路径的正确位置。然后你应该像这样加载它

new ClassPathXmlApplicationContext("beans.xml")

或者像这样

new GenericXmlApplicationContext("classpath:beans.xml");

【讨论】:

【参考方案11】:

在 Spring 中,所有源文件都在 src/main/java 中。同样,资源通常保存在 src/main/resources 中。因此,请将您的 spring 配置文件保存在资源文件夹中。

确保在 src/main/resources 中也有文件的 ClassPath 条目。

在 .classpath 中检查以下 2 行。如果缺少,请添加。

<classpathentry path="src/main/java" kind="src"/>
<classpathentry path="src/main/resources" kind="src" />

所以,如果一切就绪,下面的代码应该可以工作。

ApplicationContext ctx = new ClassPathXmlApplicationContext("Spring-Module.xml");

【讨论】:

【参考方案12】:

如果这个问题仍然困扰您并且您正在使用 Eclipse 进行开发,请查看这个 Eclipse 错误:Resources files from "src/main/resources" are not correctly included in classpath

解决方案似乎是查看项目属性、Java 构建路径、源文件夹。删除/src/main/resources 目录并再次添加。这会提醒 Eclipse 需要将这些文件复制到类路径。

当我使用 Eclipse 的“Neon”版本时,这个错误影响了我。 (在我意识到刚刚描述的简单修复之前,我感到非常沮丧)

【讨论】:

【参考方案13】:

这是因为 applicationContect.xml 或 any_filename.XML 没有放在正确的路径下。

故障排除步骤

1:在资源文件夹下添加XML文件。

2:如果您没有资源文件夹。通过右键单击项目新建 > 源文件夹来创建一个,将其命名为 resource 并将您的 XML 文件放在它下面。

【讨论】:

【参考方案14】:

我遇到了这个问题,这让我发疯了;我最终在我的 POM.xml 中发现了以下内容,这就是问题的原因:

<resources>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
        <includes>
            <include>**/*.properties</include>
        </includes>
    </resource>
</resources>

【讨论】:

【参考方案15】:

我不确定要写,但也许有人可以节省几个小时:

mvn clean

如果您的整个配置已经完美,则可以完成这项工作!

【讨论】:

【参考方案16】:

Gradle:v4.10.3

IDE:IntelliJ

我在使用 gradle 运行构建和测试时遇到了这个问题。到处复制 applicationContext.xml 并没有帮助。即使指定如下的完整路径也无济于事!

context = new ClassPathXmlApplicationContext("C:\\...\\applicationContext.xml");

解决方案(至少对于 gradle 而言)在于 gradle 处理资源的方式。对于我的 gradle 项目,我已经按照https://docs.gradle.org/current/userguide/java_plugin.html#sec:java_project_layout 中定义的方式布置了工作区

当使用默认 gradle 任务集运行测试时,包括一个“processTestResources”步骤,该步骤在 C:\.....\src\test\resources 中查找测试资源(Gradle 很有帮助提供完整路径)。

您的 .properties 文件和 applicationContext.xml 需要位于此目录中。如果资源目录不存在(就像我的情况一样),您需要在其中创建它并复制文件。在此之后,只需指定文件名就可以了。

context = new ClassPathXmlApplicationContext("applicationContext.xml");

【讨论】:

【参考方案17】:

我在这个问题上停留了一段时间,我得出了以下解决方案

    创建一个ApplicationContextAware类(这是一个实现ApplicationContextAware的类)

    ApplicationContextAware中我们只需要实现一个方法

    public void setApplicationContext(ApplicationContext context) 抛出 BeansException

    将这个新的 bean 告诉 spring 上下文(我称之为 SpringContext)

    bean id="springContext" class="packe.of.SpringContext" />

这里是代码sn-p

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class SpringContext implements ApplicationContextAware 
  private static ApplicationContext context;

  @Override
  public void setApplicationContext(ApplicationContext context) throws BeansException 
    this.context = context;
  
  public static ApplicationContext getApplicationContext() 
    return context;
  

    然后你可以在spring上下文之外调用应用程序上下文的任何方法,例如

    SomeServiceClassOrComponent utilityService SpringContext.getApplicationContext().getBean(SomeServiceClassOrComponent .class);

希望这能解决很多用户的问题

【讨论】:

【参考方案18】:

Beans.xml 或 file.XML 未放置在正确的路径下。如果您有 Maven 项目,您应该在资源文件夹下添加 XML 文件。 src -> main -> java -> 资源

【讨论】:

【参考方案19】:

我在 IntelliJ 上遇到了同样的问题。以下是我的解决方法:

1. 在 Spring 应用程序类中添加如下资源导入以及其他导入:@ImportResource("applicationContext.xml")

2. 看到 IDE 显示:Cannot resolve file 'applicationContext.xml' 并建议其预期文件的路径(这不是文件 applicationContext.xml 最初保存的资源)

3.将文件复制到预期位置,异常得到解决。

下面的屏幕截图方便参考:

但是,如果您想将其保留在资源中,请点击下面这个很棒的答案链接并添加资源路径,以便对其进行搜索。在没有上述步骤中描述的@ImportResource 的情况下,使用此设置可以解决异常:

https://***.com/a/24843914/5916535

【讨论】:

以上是关于Spring 确实存在时找不到 bean xml 配置文件的主要内容,如果未能解决你的问题,请参考以下文章

spring配置文件详解

spring配置文件详解--真的蛮详细

Spring配置文件详解

Spring实战之通过XML装配bean

Spring配置文件详解(基本涵盖所有)

解决服务器代码执行mvn test后在classes和test-classes下找不到Spring的bean.xml配置文件问题