Injecting Properties in Spring Applications

Injecting Properties in Spring Applications

Spring provides multiple mechanisms for injecting configuration properties into application components. This guide covers the primary approaches with practical examlpes.

Injecting Individual Properties with @Value

The @Value annotation directly injects a single property value into a field. This approach is ideal for simple, standalone configuration values.

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class EmailService {

    @Value("${app.email.from}")
    private String senderEmail;

    @Value("${app.email.enabled:false}")
    private boolean emailEnabled;

    public void sendEmail(String message) {
        if (emailEnabled) {
            System.out.println("Sending email from: " + senderEmail);
        }
    }
}

The syntax ${property.name} references the property, while ${property.name:default} provides a fallback value when the property is not defined.

Binding Multiple Properties with @ConfigurationProperties

For related configuration values, @ConfigurationProperties binds external properties to typed objects. This approach works well with nested configurations and provides better IDE support.

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "storage")
public class StorageConfig {

    private String bucket;
    private int maxFileSize;
    private String region;

    public String getBucket() {
        return bucket;
    }

    public void setBucket(String bucket) {
        this.bucket = bucket;
    }

    public int getMaxFileSize() {
        return maxFileSize;
    }

    public void setMaxFileSize(int maxFileSize) {
        this.maxFileSize = maxFileSize;
    }

    public String getRegion() {
        return region;
    }

    public void setRegion(String region) {
        this.region = region;
    }
}

Enable configuration properties scanning by adding @EnableConfigurationProperties to your main application class or including spring-boot-configuration-processor in your build dependencies for validation.

Accessing Properties Programmatically with Environment

The Environment interface provides direct access to property sources without field injection. This is useful when property acess is conditional or dynamic.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

@Component
public class FeatureFlagChecker {

    @Autowired
    private Environment env;

    public boolean isFeatureEnabled(String featureName) {
        String key = "feature." + featureName + ".enabled";
        return Boolean.parseBoolean(env.getProperty(key, "false"));
    }
}

Alternatively, implement EnvironmentAware for explicit dependency injection:

import org.springframework.context.EnvironmentAware;
import org.springframework.stereotype.Component;
import org.springframework.core.env.Environment;

@Component
public class ConfigLoader implements EnvironmentAware {

    private Environment env;

    @Override
    public void setEnvironment(Environment environment) {
        this.env = environment;
    }

    public String getConfigValue(String key) {
        return env.getProperty(key);
    }
}

Practical Example: Database Configuration

Consider a Spring Boot application requiring database connection settings:

@Configuration
@ConfigurationProperties(prefix = "database")
public class DataSourceConfig {

    private String hostname;
    private int port;
    private String name;
    private String username;
    private String password;

    // getters and setters omitted for brevity
}

Corresponnding application.yml configuration:

database:
  hostname: localhost
  port: 5432
  name: myapp_db
  username: dbuser
  password: ${DB_PASSWORD}

Consume the configuration in a service:

@Service
public class DatabaseService {

    private final DataSourceConfig dbConfig;

    public DatabaseService(DataSourceConfig dbConfig) {
        this.dbConfig = dbConfig;
    }

    public void initializeConnection() {
        String connectionString = String.format(
            "jdbc:postgresql://%s:%d/%s",
            dbConfig.getHostname(),
            dbConfig.getPort(),
            dbConfig.getName()
        );
        System.out.println("Connecting to: " + connectionString);
    }
}

Property Resolution Order

Spring resolves properties from multiple sources in a specific order:

  1. Command-line arguments
  2. Operating system environment variables
  3. Application properties/YAML files
  4. Profile-specific configuration files
  5. Default Spring Boot properties

Properties defined later in this sequence override earlier values, allowing environment-specific overrides without code changes.

Relaxed Binding

Spring's relaxed binding accommodates various naming conventions:

Property Name Field Name
my-property myProperty
MY_PROPERTY myProperty
my.property myProperty

This flexibility allows configuration from different sources (environment variables, YAML, properties files) without format conversion.

Tags: java Spring Dependency Injection configuration properties

Posted on Wed, 28 Oct 2026 16:45:45 +0000 by FormatteD_C