简体   繁体   English

java spring context:property-placeholder-设置占位符的属性路径

[英]java spring context:property-placeholder - set properties paths from placeholder

<context:property-placeholder
    location="a.properties,b.properties"
    ignore-unresolvable="true"/>

result: both properties file are loaded 结果:两个属性文件均已加载

<context:property-placeholder
    location="${properties_location}"
    ignore-unresolvable="true"/>

where properties_location is "a.properties,b.properties" 其中properties_location是“ a.properties,b.properties”

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

edit: ${properties_location} is set the following way: 编辑: ${properties_location}的设置方式如下:

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

How can I initialize my application the 2nd way? 如何以第二种方式初始化我的应用程序? to have all the properties file's path defined in a placeholder. 在占位符中定义所有属性文件的路径。

You have to change this to: 您必须将其更改为:

<context:property-placeholder
location="classpath:a.properties,
          classpath:b.properties"
ignore-unresolvable="true"/>

From the source of the parser for the property-placeholder element. 从解析器来源获取property-placeholder元素。

String location = element.getAttribute("location");
if (StringUtils.hasLength(location)) {
    String[] locations = StringUtils.commaDelimitedListToStringArray(location);
    builder.addPropertyValue("locations", locations);
}

First the location is retrieved, if that has a value it is converted to a String[] . 首先,获取位置,如果该位置具有值,则将其转换为String[] Springs conversion service takes care of replacing any placeholders in the String[] . Springs转换服务负责替换String[]中的所有占位符。 But at that moment the properties_location placeholder is just a single element in the array and that gets resolved to a.properties,b.properties without further processing. 但是在那时, properties_location占位符只是数组中的单个元素a.properties,b.properties无需进一步处理即可解析为a.properties,b.properties

So at the moment this isn't possible with placeholders I'm afraid. 因此,恐怕目前无法使用占位符。

One thing that might work is using SpEL if it is always going to be a system property you can use #{systemProperties['properties_location']} to resolve the value. 可能有用的一件事是使用SpEL,如果它始终是系统属性,则可以使用#{systemProperties['properties_location']}来解析该值。 That should be resolved before anything else. 那应该先解决。

You cant use a property placeholder as a value in a placeholder placeholder resolver. 您不能将属性占位符用作占位符占位符解析器中的值。 Its like saying, "hey, resolve the placeholder for the location of the all the properties, and then you can start resolving properties!". 就像说,“嘿,为所有属性的位置解析占位符,然后就可以开始解析属性了!”。

Logically it just dosent make sense. 从逻辑上讲,这只是有意义的。 I was experimenting with spring property placeholder resolution recently, and stumbled upon this same question. 我最近正在尝试使用Spring属性占位符解析,但偶然发现了这个问题。 I attempted to use two property placeholder configurers, one to resolve the location of the properties for the second, and the second to resolve the rest of the properties. 我尝试使用两个属性占位符配置器,一个用于解析第二个属性的位置,第二个用于解析其余属性。 Of course this dosent work due to the way in which spring initialises its beans. 当然,由于弹簧初始化其bean的方式,所以这很重要。

  1. Initialise bean post processors 初始化bean后处理器
  2. Construct them 构造它们
  3. Construct all other beans 构造所有其他bean

Since the property placeholder configurer is a bean post processor, if you have more than one of them, they get initialised and constructed at the same time, so know nothing of each others properties at construction 由于属性占位符配置器是一个bean后处理器,因此如果您有多个,它们会同时被初始化和构造,因此在构造时彼此一无所知

Edit 编辑

Given that the property location is a system property you could have: 鉴于属性位置是系统属性,您可以拥有:

System.getProperties().setProperty("properties_location_a", "classpath:/a.properties");
System.getProperties().setProperty("properties_location_b", "classpath:/b.properties");

And then in your spring content.xml: 然后在您的spring content.xml中:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM