环境变量未转换为系统属性

huangapple go评论71阅读模式
英文:

Environment variables not converted to system properties

问题

在处理一个基于旧版 Spring 的应用程序(Spring 4.3)时,我遇到了一个奇怪的行为:Spring 无法解析环境变量。
例如,我有这个环境变量:HOST_SERVICE_BASE_URL,当我在应用程序中使用${host.service.base.url}引用它时,属性未能解析,导致应用程序在启动时失败。

Caused by: java.lang.IllegalArgumentException: 无法解析占位符 'host.service.base.url' 中的值 "${host.service.base.url}"

我为属性解析定义了以下 bean:

@Bean
public PropertiesFactoryBean applicationProperties(ResourceLoader resourceLoader) {
    PropertiesFactoryBean propertiesFactory = new PropertiesFactoryBean();
    propertiesFactory.setLocations(
        resourceLoader.getResource("/WEB-INF/config/application.properties"),
        resourceLoader.getResource("/WEB-INF/config/application-dev.properties")
    );
    return propertiesFactory;
}

以及:

<bean id="dataConfigPropertyConfigurer"
      class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="ignoreResourceNotFound" value="true"/>
    <property name="searchSystemEnvironment" value="true"/>
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
    <property name="properties" ref="applicationProperties"/>
</bean>
英文:

Working on a legacy Spring based application (Spring 4.3), I have a strange behavior: environment variables are not resolved by Spring.
For example I have this environment variable: HOST_SERVICE_BASE_URL, when I refer to it in the application with ${host.service.base.url} the property is not resolved and the application fails during start up.

Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder &#39;host.service.base.url&#39; in value &quot;${host.service.base.url}

I defined these beans for property resolution:

    @Bean
    public PropertiesFactoryBean applicationProperties( ResourceLoader resourceLoader ) {
        PropertiesFactoryBean propertiesFactory = new PropertiesFactoryBean();
        propertiesFactory.setLocations( resourceLoader.getResource( &quot;/WEB-INF/config/application.properties&quot; ),
                    resourceLoader.getResource( &quot;/WEB-INF/config/application-dev.properties&quot; ) );
        return propertiesFactory;
    }

And

    &lt;bean id=&quot;dataConfigPropertyConfigurer&quot;
		  class=&quot;org.springframework.beans.factory.config.PropertyPlaceholderConfigurer&quot;&gt;
		&lt;property name=&quot;ignoreResourceNotFound&quot; value=&quot;true&quot;/&gt;
		&lt;property name=&quot;searchSystemEnvironment&quot; value=&quot;true&quot;/&gt;
		&lt;property name=&quot;systemPropertiesModeName&quot; value=&quot;SYSTEM_PROPERTIES_MODE_OVERRIDE&quot;/&gt;
		&lt;property name=&quot;properties&quot; ref=&quot;applicationProperties&quot;/&gt;
	&lt;/bean&gt;

答案1

得分: 2

你正在使用(现已不建议使用的)PropertyPlaceholderConfigurer,虽然它可以查看系统环境,但缺少将这些属性映射到值的功能。即HOST_SERVICE_BASE_URL没有映射为host.service.base.url

该支持仅在使用PropertySourcesPlaceholderConfigurer时才可用,它会自动注册并在Spring 5.2建议使用(但自3.1起可用)时进行查询。

&lt;bean id=&quot;dataConfigPropertyConfigurer&quot;
          class=&quot;org.springframework.context.support.PropertySourcesPlaceholderConfigurer&quot;&gt;
    &lt;property name=&quot;ignoreResourceNotFound&quot; value=&quot;true&quot;/&gt;
    &lt;property name=&quot;properties&quot; ref=&quot;applicationProperties&quot;/&gt;
&lt;/bean&gt;

或者在Java中替换applicationProperties bean和XML部分。

@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
  PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
  configurer.setLocations({&quot;/WEB-INF/config/application.properties&quot;, /WEB-INF/config/application-dev.properties&quot;});
  configurer.setIgnoreResourceNotFound(true);
  return configurer;
}

或者如果你坚持使用XML,可以使用&lt;context:property-placeholder /&gt;标签,它会自动执行此操作。

&lt;context:property-placeholder properties=&quot;applicationProperties&quot; ignore-resource-not-found=&quot;true&quot; /&gt;

或者

&lt;context:property-placeholder locations=&quot;/WEB-INF/config/application.properties,/WEB-INF/config/application-dev.properties&quot; ignore-resource-not-found=&quot;true&quot; /&gt;
英文:

You are using the (now deprecated) PropertyPlaceholderConfigurer while that can consult the system environment it lacks the feature of mapping those properties to values. I.e HOST_SERVICE_BASE_URL isn't mapped as host.service.base.url.

That support is only available in the SystemEnvironmentPropertySource which is automatically registered and consulted when using the PropertySourcesPlaceholderConfigurer (recommended as of Spring 5.2, but available since 3.1).

&lt;bean id=&quot;dataConfigPropertyConfigurer&quot;
          class=&quot;org.springframework.context.support.PropertySourcesPlaceholderConfigurer&quot;&gt;
    &lt;property name=&quot;ignoreResourceNotFound&quot; value=&quot;true&quot;/&gt;
    &lt;property name=&quot;properties&quot; ref=&quot;applicationProperties&quot;/&gt;
&lt;/bean&gt;

Or in Java to replace the applicationProperties bean and XML portion.

@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
  PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
  configurer.setLocations({&quot;/WEB-INF/config/application.properties&quot;, /WEB-INF/config/application-dev.properties&quot;});
  configurer.setIgnoreResourceNotFound(true);
  return configurer;
}

Or if you really stick with XML use the &lt;context:property-placeholder /&gt; tag, which automatically does this.

&lt;context:property-placeholder properties=&quot;applicationProperties&quot; ignore-resource-not-found=&quot;true&quot; /&gt;

or

&lt;context:property-placeholder locations=&quot;/WEB-INF/config/application.properties,/WEB-INF/config/application-dev.properties&quot; ignore-resource-not-found=&quot;true&quot; /&gt;

huangapple
  • 本文由 发表于 2020年8月13日 21:46:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/63396602.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定