对于配置文件我们原来使用spring的applicationContext.xml来配置
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<!-- standard configuration -->
<value>classpath*:/application.properties</value>
<!-- local dev configuration -->
<value>classpath*:/application.local.properties</value>
<!-- production server configuration -->
<value>classpath*:application.server.properties</value>
< </list>
</property>
</bean>
原来的配置文件是放在src/main/resources/application.properties 下面的, 但在生产/测试服务器中部署的话经常要要改动该配置文件, 先解包然后再改于是客户提出要求把配置文件放到站外.
修改如下
value>file:/var/myapp/application.server.properties</value>
但客户要求不能硬编码外部配置文件的路径, 并把这个路径放在tomcat的配置里面. 于是想改成
<value>file:${yourpath}/application.server.properties</value>
这种形式, 但这样要求yourpath为系统变量. 最后的解决方案是在tomcat的<tomcatHome>/conf/context.xml中添加一个环境变量, 然后重写了一个ContextLoaderListener
最后的配置为
<tomcatHome>/conf/context.xml
<Environment name="yourConfigPath" value="E:/"
type="java.lang.String" override="false" />
applicationContext.xml
...
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<!-- standard configuration -->
<value>classpath*:/application.properties</value>
<!-- local dev configuration -->
<value>classpath*:/application.local.properties</value>
<!-- production server configuration -->
<value>file:${yourConfigPath}/application.properties</value>
</list>
</property>
</bean>
...
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- use our listener to replace the spring listen -->
<listener>
<listener-class>com.barry.listener.ContextLoaderListener</listener-class>
</listener>
<!--
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
-->
ContextLoaderListener.java
packagecom.barry.listener;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.springframework.web.context.ContextLoader;
/**
* Bootstrap listener to start up Spring's root {@link WebApplicationContext}.
* Simply delegates to {@link ContextLoader}.
*
*
* @author barry.diao
*/
public class ContextLoaderListener implements ServletContextListener
{
private ContextLoader contextLoader;
/**
* Initialize the root web application context.
* @param event ServletContextEvent
*/
public void contextInitialized(ServletContextEvent event)
{
Context initCtx;
try
{
initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
String config = null;
config = (String) envCtx.lookup("yourConfigPath");
System.setProperty("yourConfigPath", config);
envCtx.close();
initCtx.close();
}
catch (NamingException e)
{
// e.printStackTrace();
System.setProperty("yourConfigPath", "");
}
catch (Exception ex)
{
// ex.printStackTrace();
System.setProperty("yourConfigPath", "");
}
this.contextLoader = createContextLoader();
this.contextLoader.initWebApplicationContext(event.getServletContext());
}
/**
* Create the ContextLoader to use. Can be overridden in subclasses.
*
* @return the new ContextLoader
*/
protected ContextLoader createContextLoader()
{
return new ContextLoader();
}
/**
* Return the ContextLoader used by this listener.
*
* @return the current ContextLoader
*/
public ContextLoader getContextLoader()
{
return this.contextLoader;
}
/**
* Close the root web application context.
* @param event ServletContextEvent
*/
public void contextDestroyed(ServletContextEvent event)
{
if (this.contextLoader != null)
{
this.contextLoader.closeWebApplicationContext(event.getServletContext());
}
}
}