JavaSpring上下文:属性占位符-从占位符设置属性路径

JavaSpring上下文:属性占位符-从占位符设置属性路径,java,spring,properties,Java,Spring,Properties,编辑:${properties\u location}按以下方式设置: result: Exception in thread "main" org.springframework.beans.factory.BeanInitializationException: Could not load properties; nested exception is java.io.FileNotFoundException: class path resource [a.properties,b.pr

编辑:
${properties\u location}
按以下方式设置:

result: Exception in thread "main" org.springframework.beans.factory.BeanInitializationException: Could not load properties; nested exception is java.io.FileNotFoundException: class path resource [a.properties,b.properties] cannot be opened because it does not exist

如何以第二种方式初始化应用程序?要在占位符中定义所有属性文件的路径,必须将其更改为:

System.getProperties().setProperty("properties_location", "a.properties,b.properties");
ApplicationContext ctx = new GenericXmlApplicationContext("context.xml");
...

来自
属性占位符
元素的解析器源

<context:property-placeholder
location="classpath:a.properties,
          classpath:b.properties"
ignore-unresolvable="true"/>
首先检索位置,如果该位置具有值,则将其转换为
字符串[]
。Springs转换服务负责替换
字符串[]
中的任何占位符。但此时,
properties\u location
占位符只是数组中的一个元素,它被解析为
a.properties,b.properties
,无需进一步处理

所以现在恐怕用占位符是不可能的


如果SpEL始终是一个系统属性,那么可以使用SpEL,您可以使用
{systemProperties['properties\u location']}
解析该值。这件事应该先解决

不能将属性占位符用作占位符解析程序中的值。这就像说,“嘿,解析所有属性位置的占位符,然后就可以开始解析属性了!”

从逻辑上讲,这是没有道理的。我最近在试验spring属性占位符解析,偶然发现了同样的问题。我尝试使用两个属性占位符配置器,一个用于解析第二个属性的位置,另一个用于解析其余属性。当然,这是因为spring初始化其bean的方式

  • 初始化bean后处理器
  • 建造它们
  • 构造所有其他bean
  • 由于属性占位符配置器是一个bean后处理器,如果您有多个后处理器,它们将同时初始化和构造,因此在构造时对彼此的属性一无所知

    编辑

    鉴于属性位置是系统属性,您可以:

    然后在spring content.xml中:

    
    ${properties\u location\u a}
    ${properties\u location\u b}
    
    谢谢。但这并不能回答我的问题-如何在占位符中包含这些路径。示例中的${properties\u location}设置为系统属性。我编辑了我的问题。示例中的${properties\u location}设置为系统属性。我编辑了我的问题。是的,这是一个明显的解决办法。问题是我无法在不更改java代码的情况下更改属性文件的数量;但是在spring上下文中,创建一个工厂bean,它接受该属性,在“,”上拆分它,并返回一个列表。然后在PropertyPlaceHolderConfigure上,使用属性name=“locations”ref=“listFactoryBean”?此外,它还必须实现和使用BeanPostProcessor,或者您可以指定使用哪个spring版本。问题是,占位符在
    字符串转换为
    字符串[]
    后得到解决。所以你想要的是,目前,不可能。
    System.getProperties().setProperty("properties_location", "a.properties,b.properties");
    ApplicationContext ctx = new GenericXmlApplicationContext("context.xml");
    ...
    
    <context:property-placeholder
    location="classpath:a.properties,
              classpath:b.properties"
    ignore-unresolvable="true"/>
    
    String location = element.getAttribute("location");
    if (StringUtils.hasLength(location)) {
        String[] locations = StringUtils.commaDelimitedListToStringArray(location);
        builder.addPropertyValue("locations", locations);
    }
    
    System.getProperties().setProperty("properties_location_a", "classpath:/a.properties");
    System.getProperties().setProperty("properties_location_b", "classpath:/b.properties");
    
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
      <property name="ignoreUnresolvablePlaceholders" value="true"/>
      <property name="locations">
        <list>
          <value>${properties_location_a}</value>
          <value>${properties_location_b}</value>
        </list>
      </property>
    </bean>