Spring YAML配置文件中的Profile配置

5

我不确定自己是否完全理解了Spring配置文件(包括yaml文件和properties文件)是如何使用profiles的。

我试图混合这两种类型的配置(这两个文件没有共享任何配置),但是当从yaml配置中读取配置文件时遇到了问题。

我正在使用Spring 4.1.1版本。

这是代码。这是context:property-placeholder配置:

<context:property-placeholder location="classpath:/job-config.properties" order="1" 
ignore-unresolvable="true" ignore-resource-not-found="false"/>


<context:property-placeholder properties-ref="yamlProperties" order="2"
ignore-resource-not-found="false" ignore-unresolvable="true"/>

其中yamlProperties是以下bean

    <bean id="yamlProperties" 
    class="org.springframework.beans.factory.config.YamlPropertiesFactoryBean">
                <property name="resources" 
value="file:${catalina.home}/properties/test.yml"/>
            </bean>

以下是test.yml文件内容:

spring:
  profiles.default: default
---
spring:
  profiles: default
db:
  url: jdbc:oracle:thin:@##hostname##:##port##:##SID##
  usr: ##USER##
  pwd: ##PWD##
---
spring:
  profiles: development
db:
  url: jdbc:oracle:thin:@##hostname##:##port##:##SID_DEVELOPMENT##
  usr: ##USER_DEVELOPMENT##
  pwd: ##PWD_DEVELOPMENT##

我的问题是,当我尝试通过以下方式(通过xml)配置我的数据源时:
<property name="url" value="${db.url}"/>
<property name="username" value="${db.usr}"/>
<property name="password" value="${db.pwd}"/>

Spring总是使用YAML文件中的最后一个配置,忽略了激活的配置文件。我尝试通过在web.xml中通过context-parameter或直接传递给JVM来传递激活的配置文件(我实现了一个实现EnvironmentAware接口的Bean以获取激活/默认配置文件,并且它是正确的),并且看起来一切都很好,但是当尝试注入值时,配置文件被忽略了。
我认为使用property-placeholder上下文(具有顺序)可以获得一个property-placeholder,它是PropertySourcesPlaceholderConfigurer的实例,因此可以访问Environment,但我无法理解为什么会忽略配置文件,并且Spring获取了YAML文件的最后一个配置。
我附加了对文档(spring-boot)的引用,在第63.6节http://docs.spring.io/spring-boot/docs/current/reference/html/howto-properties-and-configuration.html 提前感谢!

我通过实现自己的PropertiesFactory解决了这个问题。我从Spring Boot核心中导入了YamlProcessor(而不是Spring Core)和SpringProfileDocumentMatcher。我的类还实现了EnvironmentAware接口。我更改了createProperties()方法,以便读取活动配置文件并设置正确的DocumentMatcher。 - Raffaele
这是代码String [] activeProfiles = env.getActiveProfiles(); if(activeProfiles.length==0){ this.setMatchDefault(true); this.setDocumentMatchers(new SpringProfileDocumentMatcher()); }else{ this.setMatchDefault(false); SpringProfileDocumentMatcher matcher = new SpringProfileDocumentMatcher(); for(String profile : activeProfiles) { matcher.addActiveProfiles(profile); } this.setDocumentMatchers(matcher); } - Raffaele
我遇到了类似的问题。这是我的解决方案:https://dev59.com/Mafja4cB1Zd3GeqPu2FV - James
1个回答

4

不确定这是否有所帮助,但这是我的做法。

我使用了Spring Boot中的SpringProfileDocumentMatcher类[由Dave Syer创建]作为基本匹配器,并实现了EnvironmentAware以获取活动配置文件并将此bean传递给YamlPropertiesFactoryBean bean。以下是代码:

applicationContext.xml

<bean id="yamlProperties" class="org.springframework.beans.factory.config.YamlPropertiesFactoryBean">
<property name="resources" value="classpath:application.yml" />
<property name="documentMatchers">
  <bean class="com.vivastream.quant.spring.SpringProfileDocumentMatcher" />
</property>

SpringProfileDocumentMatcher.java

public class SpringProfileDocumentMatcher implements DocumentMatcher, EnvironmentAware {

private static final String[] DEFAULT_PROFILES = new String[] {
        "^\\s*$"
};

private String[] activeProfiles = new String[0];

public SpringProfileDocumentMatcher() {
}

@Override
public void setEnvironment(Environment environment) {
    if (environment != null) {
        addActiveProfiles(environment.getActiveProfiles());
    }
}

public void addActiveProfiles(String... profiles) {
    LinkedHashSet<String> set = new LinkedHashSet<String>(Arrays.asList(this.activeProfiles));
    Collections.addAll(set, profiles);
    this.activeProfiles = set.toArray(new String[set.size()]);
}

@Override
public MatchStatus matches(Properties properties) {
    String[] profiles = this.activeProfiles;
    if (profiles.length == 0) {
        profiles = DEFAULT_PROFILES;
    }
    return new ArrayDocumentMatcher("spring.profiles", profiles).matches(properties);
}

}


谢谢Gustavo,基本上我采用了类似的解决方案。再次感谢。 - Raffaele
ArrayDocumentMatcher,应该从哪里获取? - vlio20

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接