Backend Development 10 min read

Analyzing Spring Boot 2.2.0.RELEASE Configuration Loading Mechanism

This article examines how Spring Boot 2.2.0.RELEASE loads configuration files, where it searches for them, how it supports YAML and properties formats, how to add JSON support, the precedence of property sources, and the placeholder resolution process by tracing the relevant source code.

Architecture Digest
Architecture Digest
Architecture Digest
Analyzing Spring Boot 2.2.0.RELEASE Configuration Loading Mechanism

The article investigates Spring Boot version 2.2.0.RELEASE by reading its source code to answer common configuration questions such as where the loading starts, which locations are scanned, how YAML and properties files are handled, how to add JSON support, the priority order of configuration sources, and how placeholders are resolved.

Where does Spring Boot start loading configuration files? The entry point is the ApplicationEnvironmentPreparedEvent . Spring Boot registers a ConfigFileApplicationListener via the spring.factories file, which listens for this event and triggers the loading process. The event is dispatched by SpringApplicationRunListeners , which itself is created from listeners defined in spring.factories (e.g., EventPublishingRunListener ).

public SpringApplication(ResourceLoader resourceLoader, Class
... primarySources) {
    ...
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    ...
}
# Application Listeners
org.springframework.context.ApplicationListener= org.springframework.boot.context.config.ConfigFileApplicationListener
...
class SpringApplicationRunListeners {
    private final Log log;
    private final List<SpringApplicationRunListener> listeners;
    SpringApplicationRunListeners(Log log, Collection<? extends SpringApplicationRunListener> listeners) {
        this.log = log;
        this.listeners = new ArrayList<>(listeners);
    }
    void environmentPrepared(ConfigurableEnvironment environment) {
        for (SpringApplicationRunListener listener : this.listeners) {
            listener.environmentPrepared(environment);
        }
    }
    ...
}

From which locations does Spring Boot load configuration files? The listener uses two constants:

private static final String DEFAULT_SEARCH_LOCATIONS = "classpath:/,classpath:/config/,file:./,file:./config/";
private static final String DEFAULT_NAMES = "application";

Without any custom settings, Spring Boot searches the default locations for files named application.properties or application.yml . If the properties spring.config.location or spring.config.additional-location are defined, those values are used together with the defaults.

private Set<String> getSearchLocations() {
    if (this.environment.containsProperty(CONFIG_LOCATION_PROPERTY)) {
        return getSearchLocations(CONFIG_LOCATION_PROPERTY);
    }
    Set<String> locations = getSearchLocations(CONFIG_ADDITIONAL_LOCATION_PROPERTY);
    locations.addAll(asResolvedSet(this.searchLocations, DEFAULT_SEARCH_LOCATIONS));
    return locations;
}

How does Spring Boot support YAML and properties files? The ConfigFileApplicationListener.Loader loads PropertySourceLoader implementations declared in spring.factories :

# PropertySource Loaders
org.springframework.boot.env.PropertySourceLoader=\
org.springframework.boot.env.PropertiesPropertySourceLoader,\
org.springframework.boot.env.YamlPropertySourceLoader

The two loaders, PropertiesPropertySourceLoader and YamlPropertySourceLoader , parse the respective formats and produce PropertySource objects.

How to add JSON configuration support? Implement a custom PropertySourceLoader (e.g., JSONPropertySourceLoader ) and register it in a META-INF/spring.factories file:

public class JSONPropertySourceLoader implements PropertySourceLoader {
    @Override
    public String[] getFileExtensions() {
        return new String[] {"json"};
    }
    @Override
    public List<PropertySource<?>> load(String name, Resource resource) throws IOException {
        if (resource == null || !resource.exists()) {
            return Collections.emptyList();
        }
        Map<String, Object> configs = JSON.parseObject(resource.getInputStream(), Map.class);
        return Collections.singletonList(new MapPropertySource(name, configs));
    }
}
org.springframework.boot.env.PropertySourceLoader=\
com.csbaic.arch.spring.env.loader.JSONPropertySourceLoader

After adding application.json to the classpath, Spring Boot will read the JSON properties like any other source.

Configuration priority is managed by the MutablePropertySources collection. Each PropertySource (e.g., CommandLinePropertySource , SystemEnvironmentPropertySource , etc.) is stored in a list; a lower index means higher precedence, and developers can add, remove, or reorder sources via methods such as addFirst , addLast , addBefore , and addAfter .

public void addFirst(PropertySource
propertySource) {}
public void addLast(PropertySource
propertySource) {}
public void addBefore(String relativePropertySourceName, PropertySource
propertySource) {}
public void addAfter(String relativePropertySourceName, PropertySource
propertySource) {}
public int precedenceOf(PropertySource
propertySource) { }
public PropertySource
remove(String name) {}
public void replace(String name, PropertySource
propertySource) {}

How are placeholders resolved? The loader creates a PropertySourcesPlaceholdersResolver , which internally uses PropertyPlaceholderHelper with the standard Spring placeholder syntax ( ${...} and optional default value separator : ).

public PropertySourcesPlaceholdersResolver(Iterable<PropertySource<?>> sources, PropertyPlaceholderHelper helper) {
    this.sources = sources;
    this.helper = (helper != null) ? helper : new PropertyPlaceholderHelper(
        SystemPropertyUtils.PLACEHOLDER_PREFIX,
        SystemPropertyUtils.PLACEHOLDER_SUFFIX,
        SystemPropertyUtils.VALUE_SEPARATOR, true);
}

Thus a placeholder like ${spring.application.name} is replaced with the corresponding property value during environment preparation.

Conclusion – Spring Boot’s configuration system is highly flexible: it can read files from multiple locations, supports several formats via pluggable loaders, allows custom formats such as JSON, manages source precedence through MutablePropertySources , and resolves placeholders uniformly, providing developers with a powerful and extensible configuration abstraction.

BackendJavaConfigurationJSONSpring BootYAMLPropertySource
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.