對于配置檔案我們原來使用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());
}
}
}