In a previous post, we discovered how auto-configuration in Spring Boot enables bean and configuration creation.
In Spring, managing settings, configuring beans, or handling application constants, properly injecting properties into the environment is crucial. Here we’ll explore different methods of injecting properties in a Spring Boot auto-configuration setup.
Programmatic Property Injection
One method for injecting properties is programmatically adding them to the ConfigurableEnvironment
.
@Configuration public class ConfigInjection { @Autowire ConfigurableEnvironment environment; @PostConstruct public void performAction() { environment.getPropertySources().addFirst(new PropertiesPropertySource("propKey", "propValue")); } }
Using @PropertySource
with application.properties
Another simple case is using application.properties
or application.yml
files in combination with the @PropertySource
annotation.
@PropertySource(value = "classpath:foo.properties")
However, here we have some limitations, when using @PropertySource
. For example, Spring Boot loads certain properties, like logging.*
and spring.main.*
, before the application context is refreshed. This means these properties cannot be configured through @PropertySource
because they are needed too early in the lifecycle.
You can read more about this in the Spring Boot external configuration documentation.
such property sources are not added to the
Environment
until the application context is being refreshed. This is too late to configure certain properties such aslogging.*
andspring.main.*
which are read before refresh begins.
When Does the Context Get Refreshed?
The context is refreshed during the initialization phase of a Spring application, but before the application starts running.
Specifically, this happens after the beans are instantiated but before certain critical configurations—like logging properties (logging.*
) or Spring Boot’s core settings (spring.main.*
)—are applied.
These particular properties need to be set early because they control foundational behaviors like logging, classpath scanning, and profile management, which need to be established before the application context is fully created and refreshed.
So properties required early need to be set before the context refresh process, typically through external configuration files like application.properties
or environment variables, or programatically, not by @PropertySource
.
Injecting Properties for Bean Creation
If you want to inject properties into beans at the time of their creation, you can use the @Value
annotation:
@Component public class MyBean { @Value("${property.injectable.at.bean.creation.time}") private String name; // ... }
Setting up properties before App Context Creation
Defining properties before the application context is created, you can implement an ApplicationContextInitializer
in your auto-conf library:
In the META-INF/spring.factories
file or META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
, you would register your initializer:
org.springframework.context.ApplicationContextInitalizer=\
com.example.config.MyPropConfiguration
Sample implementation:
public class MyPropConfiguration implements ApplicationContextInitalizer<ConfigurableApplicationContext>{ @Override public void initalize(ConfigurableApplicationContext appContext){ appContext.getEnvironment().getPropertySources().addFirst( new PropertiesPropertySource("propKey", "propValue") ) } }
Conclusion
We wnt through on multiple approaches to injecting properties in a Spring Boot application, with their advantages and disadvantages. depending on the specific needs. Understanding these different methods enables you to make better decisions choosing configurations across different environments and stages of your application lifecycle.
Programmatic injection allows flexible configuration at runtime, where properties need to be defined or modified on the fly.
On the other hand, using @PropertySource
simplifies configuration by loading properties from external files, with the limitations when dealing with early-loaded settings, such as logging and core Spring Boot properties.
In case where properties needed before the appContext is fully initialized, implementing an ApplicationContextInitializer
can help, ensuring that configurations are loaded early.
Ultimately, the choosing right method to manage configs can significantly improve the maintainability or in complex cases the scalability, and flexibility of your application.
One thought on “Expanding on Property Injection with Spring Boot Auto-Configuration”