为什么Spring的PropertySource会抛出FileNotFoundException?

时间:2016-11-11 03:18:59

标签: java spring-mvc

我正在尝试使用Spring加载属性文件,该文件位于我的entity_user(user_id, entity_id)文件夹中。

我收到以下错误:

  

org.springframework.beans.factory.BeanDefinitionStoreException:失败   解析配置类[com.elastictest.config.ProdConfig];   嵌套异常是java.io.FileNotFoundException:   \ WEB-INF \ config \ prod.properties(系统找不到路径   指定)

这是我的生产配置文件:

WEB-INF

这是我的web.xml声明:

@Configuration
@Profile("prod")
@PropertySource("file:${prodPropertiesFile}")
public class ProdConfig {

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

}

我打开了战争并验证了属性文件在WEB-INF / config文件夹下。有什么想法吗?

3 个答案:

答案 0 :(得分:3)

locations注释中指定的@PropertySourceResourceLoader处理。在这种情况下,这将是您的AnnotationConfigWebApplicationContext,因为这是一个Web应用程序,您想要使用注释配置。

作为ResourceLoader实施,AnnotationConfigWebApplicationContext知道如何解析位置值以查找和初始化Resource个对象。它使用这些来创建在属性解析中使用的ResourcePropertySource个对象。

位置值分辨率遵循以下几个步骤:

  • 如果它以/开头,则将其解释为servlet上下文资源,Spring会尝试通过ServletContext#getResourceAsStream检索它。
  • 如果以classpath:开头,则将其解释为类路径资源,并且Spring会尝试通过ClassLoader#getResourceAsStream检索它,并给出相应的ClassLoader
  • 否则,它会将解析推迟到使用URL定位资源的UrlResource。它的javadoc陈述

      

    URL协议的情况下支持File"file:"的分辨率。

在您的情况下,您使用file:为您的位置添加前缀,以便Spring尝试使用UrlResource。您的路径有一个前导/,文件系统将其视为绝对路径的开头。您显然没有该位置的文件/WEB-INF/config/prod.properties

如果您使用this answer中建议的classpath:前缀,则必须确保/WEB-INF/config/prod.properties位于类路径中。这是一个非常不常见的事情,所以我不推荐它。

最后,正如您所知,您可以使用

@PropertySource("/WEB-INF/config/prod.properties")
// or to support your property
@PropertySource("${prodPropertiesFile}")

将尝试通过ServletContext检索资源。它的javadoc陈述

  

路径必须以/开头,并且被解释为相对于当前上下文根

您的WEB-INF文件夹将位于上下文根目录中(基本上是为您的Servlet容器选择的目录,作为Web应用程序的根目录),因此将找到并使用该资源。

您可以在官方文档here以及Resource流程here中详细了解ResourceLoader

答案 1 :(得分:-1)

无需web.xml声明。试试这个

private bool isDataUri(string src)...
private bool isAbsoluteUrl(string src)...
private bool isRelativeUrl(string src)...

答案 2 :(得分:-1)

事实证明它比我做的更简单:

DefaultMessageListenerContainer