从战争中

时间:2015-06-19 05:57:53

标签: java spring hibernate tomcat

我已将战争中的配置文件外部化,我想知道如何解决我在应用程序上下文中被强制提供的绝对位置,以使其工作。

在我的web.xml中,我有这个 -

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>file:C:/Program%20Files/somedirectory/webappContext.xml</param-value>
</context-param>

C:/Program%20Files/somedirectory/webappContext.xml有一个条目如下:

<import resource="applicationContext-persistence.xml" />

应用程序上下文 - persistence.xml与webAppContext.xml位于同一目录中,并且有一行 -

<util:properties id="hibernateProperties" location="hibernate.properties" />
<encryption:encryptable-property-placeholder encryptor="stringEncryptor" location="hibernate.properties"/> 

Tomcat无法找到位于同一目录中的hibernate.properties文件。相反,它迫使我将其定义如下:

<util:properties id="hibernateProperties" location="file:C:/Program%20Files/somedirectory/hibernate.properties" />
<encryption:encryptable-property-placeholder encryptor="stringEncryptor" location="file:C:/Program%20Files/somedirectory/hibernate.properties"/>

有没有办法绕过指定完整路径?为什么webAppContext.xml中的行工作而不是applicationcontext-persistence.xml中的行?两者在性质上与引用位于同一目录中的文件类似。

2 个答案:

答案 0 :(得分:1)

webappContext.xml应该驻留在WAR中,但它可以包含以下内容:

<bean id="coreProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="locations">
        <list>
            <value>classpath:/properties/*.properties</value>
            <value>file:${app.home}/properties/*.properties</value>
        </list>
    </property>
</bean>

 <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="ignoreUnresolvablePlaceholders" value="true"/>
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
    <property name="ignoreResourceNotFound" value="false"/>

    <property name="properties" ref="coreProperties" />
</bean>

现在,您只需在应用程序启动时传递app.home系统属性:

# cat setenv.sh
export CATALINA_OPTS="$CATALINA_OPTS -Dapp.home=/home/user/my-app"

答案 1 :(得分:1)

你试图欺骗框架,它不想帮你做。

更严重的是,它是在应用程序上下文中解析资源的方式。从doc中提取当前版本的Spring Framework:

Prefix      Example                        Explanation
classpath:  classpath:com/myapp/config.xml Loaded from the classpath.
file:       file:///data/config.xml        Loaded as a URL, from the filesystem
http:       http://myserver/logo.png       Loaded as a URL.
(none)      /data/config.xml               Depends on the underlying ApplicationContext.

当您使用WebApplicationContext(Web应用程序的常规...)时,将在应用程序的根目录下搜索不合格的资源。

但这不是全部,同样的医生后来说:

FileSystemApplicationContext只是强制所有连接的FileSystemResource实例将所有位置路径视为相对路径,无论它们是否以前导斜杠开头。实际上,这意味着以下内容是等效的:

ApplicationContext ctx = new FileSystemXmlApplicationContext("conf/context.xml");
ApplicationContext ctx = new FileSystemXmlApplicationContext("/conf/context.xml");

这意味着,如果不使用自定义ResourceLoader,则无法使用相对路径,并且只要资源不在战争中,就必须使用file:full_path_to_file

无论如何,你肯定不想那样做:你的战争现在不能部署在你自己的服务器的任何其他系统中!确实有可能在战争之外拥有(小)部分配置,它有意义,因为某些元素可能只在部署时才知道。有两种可移植的方法:

  • 使用环境变量,因为它们可用于解析spring配置中的占位符:这主要用于简单配置数据:网站管理员电子邮件,邮件服务器,后端URL或在不同profiles之间动态选择< / LI>
  • 使用servlet容器配置和JNDI:这通常用于数据库配置