PropertyPlaceholderConfigurer:使用外部属性文件

时间:2013-07-03 08:47:35

标签: spring configuration

如何配置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

4 个答案:

答案 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);
    }
}