【问题标题】:PropertyPlaceholderConfigurer: Use external properties filePropertyPlaceholderConfigurer:使用外部属性文件
【发布时间】:2013-06-30 21:07:11
【问题描述】:

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

【问题讨论】:

  • 所以属性文件在战争之外?
  • 如果你发布你的目录结构,我可以给你一个更好的答案。
  • 添加了一些信息。
  • 您需要将包含属性文件的目录添加到运行时类路径。然后使用classpath: 前缀来获取它。

标签: spring configuration


【解决方案1】:

在您的配置中,您可以从classpath 指定属性,而不是相对于配置文件。

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <property name="locations" value="classpath:com/foo/jdbc.properties"/>
</bean>

为此,您必须确保属性文件进入类路径。

【讨论】:

    【解决方案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);
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      我的代码,基于 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() {
              File resourceFile = new File(getAbsoluteFileLocation());
              return resourceFile.exists();
          }
      
          @Override
          public boolean isOpen() {
              return true;
          }
      
          @Override
          public InputStream getInputStream() throws IOException {
              return new FileInputStream(getAbsoluteFileLocation());
          }
      
          private String getAbsoluteFileLocation() {
              return Paths.get("").toAbsolutePath().resolve(relativePath).toString();
          }
      }
      

      之后我们可以在xml中写入例如:

      <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>
      

      此方法的优点 - 您无需破解 Spring Context 并且不坚持这种破解的上下文实现,您可以使用 Spring 分发中的任何(例如,不是 XmlWebApplicationContext,而是 ClassPathXmlApplicationContext)。

      【讨论】:

        【解决方案4】:

        不知何故,我无法按照其他人的方法获得所需的路径,所以这是我的工作版本,主要基于 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);
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-07-18
          • 2012-03-24
          • 1970-01-01
          • 1970-01-01
          • 2013-08-12
          • 2011-04-25
          • 2013-08-21
          • 2010-12-08
          相关资源
          最近更新 更多