Use Spring profiles and yaml configuration without Spring Boot

That's a refinement you can do to updgrade legacy applications. Using yaml config files combines with Spring profiles is a great way to configure your apps. Let's see how to do that.

Firstly, let's consider that we weill inject something in a java class depending on the runtime  environment.

public class MyService {

private String URL;


application.yaml should be like this :


  profiles: production


Thus, if I lauch my applicatin without JVM Spring profile params, URL will be If I launch it with, URL will be Great! But this feature is natively supported only for Spring Boot based applications. So, let's active this on legacy apps with this XML spring config file fragment :

<bean id="yamlProperties"
<property name="resources">
<property name="documentMatchers">
class="mypackage.SpringProfileDocumentMatcher" />
<context:property-placeholder properties-ref="yamlProperties" />

Of course, you saw that we wrote our custom SpringProfileDocumentMatcher.

import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Properties;
import java.util.Set;

import org.springframework.beans.factory.config.YamlProcessor.DocumentMatcher;
import org.springframework.beans.factory.config.YamlProcessor.MatchStatus;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;

 * Allows to use Spring profiles without Spring Boot for legacy Spring based apps
 * @author Alexandre de Pellegrin
public class SpringProfileDocumentMatcher implements DocumentMatcher, EnvironmentAware {

private static final String[] DEFAULT_PROFILES = new String[] { "default" };

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

public SpringProfileDocumentMatcher() {

public SpringProfileDocumentMatcher(String... profiles) {

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

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

public void setEnvironment(Environment environment) {
if (environment != null) {

private class ArrayDocumentMatcher implements DocumentMatcher {

private final String key;

private final String[] patterns;

public ArrayDocumentMatcher(final String key, final String... patterns) {
this.key = key;
this.patterns = patterns;


public MatchStatus matches(Properties properties) {
if (!properties.containsKey(this.key)) {
return MatchStatus.ABSTAIN;
Set values = StringUtils.commaDelimitedListToSet(properties
for (String pattern : this.patterns) {
for (String value : values) {
if (value.matches(pattern)) {
return MatchStatus.FOUND;
return MatchStatus.NOT_FOUND;

That's it!