如何配置PropertyPlaceholderConfigurer以使用与战争相关的属性文件(某些目录)?
我们多次运行战争,每场战争应该从../../etc/db.properties
读取其配置。
更新
是的,属性文件在战争之外。目录结构是:
/htdocs/shop/live/apache-tomat/webapps/shop.war
应该读
/htdocs/shop/live/etc/db.properties
和
/htdocs/shop/test/apache-tomat/webapps/shop.war
应该读
/htdocs/shop/test/etc/db.properties
答案 0 :(得分:2)
最后,我们引入了一种新的资源类型“relative:”:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<value>classpath:db.properties</value>
<value>relative:../../../etc/db.properties</value>
</list>
</property>
</bean>
我们扩展了XmlWebApplicationContext以注入自定义资源处理:
public class Context extends XmlWebApplicationContext {
@Override
public Resource getResource(String location) {
if (location.startsWith(RelativeResource.RELATIVE_URL_PREFIX)) {
String relativePath = location.substring(RelativeResource.RELATIVE_URL_PREFIX.length());
return new RelativeResource(getServletContext(), relativePath);
}
return super.getResource(location);
}
}
以下是相关资源类:
public class RelativeResource extends AbstractResource {
public static final String RELATIVE_URL_PREFIX = "relative:";
private final ServletContext servletContext;
private final String relativePath;
public RelativeResource(ServletContext servletContext, String relativePath) {
this.servletContext = servletContext;
this.relativePath = relativePath;
}
@Override
public String getDescription() {
return "RelativeResource [" + relativePath + "]";
}
@Override
public boolean isReadable() {
return true;
}
@Override
public boolean isOpen() {
return true;
}
@Override
public InputStream getInputStream() throws IOException {
String rootPath = WebUtils.getRealPath(servletContext, "/");
if (!rootPath.endsWith(File.separator)) rootPath += File.separator;
String path = rootPath + relativePath;
return new FileInputStream(path);
}
}
答案 1 :(得分:1)
我的代码,基于mazatwork解决方案:
<bean id="configurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:application.properties</value>
<value type="com.blabla.RelativeResource">overrideProperties.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="true"/>
</bean>
之后我们可以用xml编写例如:
Picasso.with(context).load("image url").fetch();
此方法的优点 - 您不会破解Spring Context并且不会坚持这种被黑客攻击的上下文实现,您可以使用Spring发布中的任何(例如,不是XmlWebApplicationContext,但是ClassPathXmlApplicationContext)。 p>
答案 2 :(得分:0)
在您的配置中,您可以从classpath
而不是相对于配置文件指定属性。
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="classpath:com/foo/jdbc.properties"/>
</bean>
要使其工作,您必须确保属性文件使其成为类路径。
答案 3 :(得分:0)
不知怎的,我无法按照别人的方法获得所需的路径,所以这是我的工作版本,主要基于Dmitry的答案(在xml中的用法是相同的),而isReadable()和getInputStream()看起来更像mazatwork的版本:
public class RelativeResource extends AbstractResource {
private final String relativePath;
public RelativeResource(String relativePath) {
this.relativePath = relativePath;
}
@Override
public String getDescription() {
return "RelativeResource [" + relativePath + "]";
}
@Override
public boolean isReadable() {
return true;
}
@Override
public boolean isOpen() {
return true;
}
@Override
public InputStream getInputStream() throws IOException {
String rootPath = this.getClass().getResource("/").getPath();
rootPath = URLDecoder.decode(rootPath, "UTF-8");
if (!rootPath.endsWith(File.separator)) rootPath += File.separator;
String path = rootPath + relativePath;
return new FileInputStream(path);
}
}