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


76

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

我收到以下IOException:

线程“主”中的异常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在类路径中。怎么了?


您如何加载上下文?
Aleksandr M

Answers:


165

谢谢,但是那不是解决方案。我发现了为什么它对我不起作用。

由于我做了一个声明:

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)所遵循的约定(请注意:作为默认配置!)。当代码(从帖子中)处于运行模式时,由于bean.xml位于jar的根目录(复制到/ beans)中,因此找不到“ src / main / resources / beans.xml”之类的内容.xml在创建的jar / ear / war中)。

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

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

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


我不明白之间的差别ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
弗洛里安˚F

1
@FlorianF没有区别。区别在于文件放置的位置,即帖子中描述的内容。
dawrutowicz

2
我看到您更改beans.xmlsrc/main/resources/beans.xml,然后更改为beans.xml。谢谢。
Florian F

您不应该在类路径上有src。当您构建项目时,这些资源将打包在其他位置。
OrangeDog

1
嗨,如果我们从命令行运行此jar,它似乎无法按预期运行(在Eclipse上可以正常工作)。
Dhruv Singhal '18年

58

尝试这个:

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

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

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


1
好吧,将资源保留在类路径中比将其硬编码为好,但是,谢谢。那时我没有CP经验:-)
dawrutowicz 2014年

1
对文件使用FileSystemXmlApplicationContext可能更好。
romnempire

我有类似的问题,此解决方案为我工作。
Avdhut

20

我也遇到了类似的问题,但由于原因稍有不同,因此在这里分享以防万一。

我的档案位置

beans.xml文件

我如何使用

ClassPathXmlApplicationContext("beans.xml");

有两种解决方案

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

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


1
好吧,可以这么说。引用“ com / mypackage / beans.xml”与“ /com/mypackage/beans.xml”相同,因为“ com / mypackage / beans.xml”是使用“ /”(根)构建绝对路径的相关路径。
dawrutowicz 2015年

7

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

new ClassPathXmlApplicationContext("beans.xml")

或者像这样

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

7

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

故障排除步骤

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

2:如果没有资源文件夹。通过右键单击new来导航新项目,然后单击“新建”> Source Folder,将其命名为资源,然后将XML文件放置在它下面。


4

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


3

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



3

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

如果appliationContext.xml<META-INF/spring/>已经声明了<import resource="beans.xml"/>,然后这个appliationContext.xml被加载beans.xml的同一位置下META-INF/springappliationContext.xml

哪里 在代码中;如果像下面这样声明

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

这是WEB-INF/classes在eclipse中的OR处查找bean.xml src/main/resources

[如果添加了beans.xmlat,src/main/resources则可能在WEB-INF/classes创建WAR时将其放置在。]

因此,总共查找了两个文件。

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

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

并删除了ClassPathXmlApplicationContext("beans.xml")Java代码中的这一行,因此将仅加载一个ApplicationContext。


2

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

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

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

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

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

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


1

摇篮: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");

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访问bean xml文件。


0

这对我有用:

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

嗨,这也对我有用,但是问题是在构建jar文件时,该jar对我来说没有运行。.我的意思是,当我在Eclipse中运行应用程序时,我在尝试运行jar文件时遇到了NoClassDefFoundError作为Java,它运行时没有错误,不确定如何解决
Sailaja

0

如果这个问题仍然困扰着您,并且您正在使用Eclipse进行开发,请查看以下Eclipse错误: “ src / main / resources”中的资源文件未正确包含在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

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

  1. 创建一个ApplicationContextAware类(这是实现ApplicationContextAware的类)
  2. ApplicationContextAware中,我们只需要实现一种方法

    公共无效setApplicationContext(ApplicationContext context)引发BeansException

  3. 告诉spring上下文有关这个新bean(我称之为SpringContext)

    bean id =“ springContext” class =“ packe.of.SpringContext” />
    

这是代码片段

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;
  }
}
  1. 然后,您可以在spring上下文之外调用应用程序上下文的任何方法,例如

    SomeServiceClassOrComponent实用工具Service SpringContext.getApplicationContext()。getBean(SomeServiceClassOrComponent .class);
    

我希望这可以解决许多用户的问题


0

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.