当Spring xml配置文件存在时,它找不到它

问题描述 投票:65回答:16

我试图在Spring中创建我的第一个bean但是在加载上下文时遇到了问题。我在src / main / resources中有一个bean的配置XML文件。

我收到以下IOException:

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

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在类路径中。怎么了?

spring configuration javabeans applicationcontext
16个回答
138
投票

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

自从我做了一个宣言:

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

当bean.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中以及稍后在classpath中的路径。

可以通过使用归档程序(即rar)解压缩jar来验证它,并使用目录结构查看其内容。

我建议阅读有关classpath的文章作为补充。


2
投票

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

确保在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”);


0
投票

我做了与大多数人相反的事情。我正在使用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文件。


0
投票

这对我有用:

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

0
投票

如果这个问题仍然让你感到困惑,并且你正在使用Eclipse进行开发,请看看这个Eclipse bug:Resources files from "src/main/resources" are not correctly included in classpath

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

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


0
投票

我遇到了这个问题,它让我疯狂;我最终发现以下内容位于我的POM.xml中,这是导致问题的原因:

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

0
投票

我不确定写它但也许有人节省几个小时:

mvn clean

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


0
投票

Gradle:inc

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:\ _ \ _s \ src \ test \ resources中查找测试资源(Gradle帮助提供完整路径)。

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

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

46
投票

试试这个:

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

file:preffix指向文件系统资源,而不是classpath。

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


18
投票

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

我的档案位置

我是怎么用的

ClassPathXmlApplicationContext("beans.xml");

有两种解决方案

  1. 从包中取出beans.xml并放入默认包。
  2. 使用时指定包名称即可。

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


6
投票

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

new ClassPathXmlApplicationContext("beans.xml")

或者像这样

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

4
投票

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


3
投票

你看过src目录。那里确实存在xml文件。但请查看设置所有输出类的class或bin / build目录。我怀疑你只需要资源/ beans.xml路径来使用。


3
投票

我怀疑你正在构建.war / .jar,因此它不再是文件,而是该包中的资源。试试ClassLoader.getResourceAsStream(String path)吧。


3
投票

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

故障排除步骤

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

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


2
投票

请注意,第一个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");

查看differencebeans.xml之间的applicationContext.xml

如果appliationContext.xml下的<META-INF/spring/>宣布与<import resource="beans.xml"/>,那么这个appliationContext.xml正在加载beans.xmlMETA-INF/spring的同一位置appliationContext.xml

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

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

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

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

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

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

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

并删除了java代码中的ClassPathXmlApplicationContext("beans.xml")行,这样只会加载一个ApplicationContext。

© www.soinside.com 2019 - 2024. All rights reserved.