Kezdő Olvasási idő: ~8 perc

Konfiguráció

application.properties, application.yml, @Value, @ConfigurationProperties, config precedence

Konfiguráció

1. Definíció

A Spring Boot konfiguráció a külső beállítások (property-k, profilok, titkos adatok) kezelésének rendszere. A Spring Boot az externalized configuration elvet követi: az alkalmazás viselkedését a kódon kívüli forrásokból (property fájlok, környezeti változók, parancssori argumentumok) vezérli.

A két fő konfigurációs formátum:

  • application.properties — egyszerű kulcs-érték párok
  • application.yml — YAML hierarchia (indentáció-alapú)
# application.properties
server.port=8081
spring.datasource.url=jdbc:postgresql://localhost/mydb
# application.yml
server:
  port: 8081
spring:
  datasource:
    url: jdbc:postgresql://localhost/mydb

2. Alapfogalmak

Property source hierarchia

A Spring Boot 17+ forrásból olvas konfigurációt. A magasabb prioritás felülírja az alacsonyabbat:

  1. Parancssori argumentumok (--server.port=9090)
  2. SPRING_APPLICATION_JSON (inline JSON)
  3. Servlet/JNDI paraméterek
  4. OS környezeti változók (SERVER_PORT=9090)
  5. Profil-specifikus property fájlok (application-prod.properties)
  6. Alkalmazás property fájlok (application.properties)
  7. @PropertySource annotáció
  8. Default properties (SpringApplication.setDefaultProperties)

@Value annotáció

Egyedi property-k injektálása:

@Component
public class MyComponent {
    @Value("${server.port}")
    private int port;

    @Value("${app.name:DefaultApp}")
    private String appName; // default érték kettőspont után

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

@ConfigurationProperties

Típusbiztos property binding egy POJO-ra:

@ConfigurationProperties(prefix = "app.datasource")
public class DataSourceProperties {
    private String url;
    private String username;
    private String password;
    private int maxPoolSize = 10;

    // getterek és setterek
    public String getUrl() { return url; }
    public void setUrl(String url) { this.url = url; }
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    public String getPassword() { return password; }
    public void setPassword(String password) { this.password = password; }
    public int getMaxPoolSize() { return maxPoolSize; }
    public void setMaxPoolSize(int maxPoolSize) { this.maxPoolSize = maxPoolSize; }
}

Profilok

Környezet-specifikus konfiguráció:

# application-dev.properties
server.port=8080
spring.datasource.url=jdbc:h2:mem:devdb

# application-prod.properties
server.port=443
spring.datasource.url=jdbc:postgresql://prod-host/mydb

Aktiválás: spring.profiles.active=dev vagy --spring.profiles.active=prod.

3. Gyakorlati használat

Property fájl elhelyezés

src/main/resources/
├── application.properties          ← alapértelmezett
├── application.yml                 ← alternatíva (YAML)
├── application-dev.properties      ← dev profil
├── application-prod.properties     ← prod profil
└── application-test.properties     ← test profil

YAML előnyök és hátrányok

# Hierarchikus struktúra — olvashatóbb
spring:
  datasource:
    url: jdbc:postgresql://localhost/mydb
    username: admin
    password: secret
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
  • ✅ Hierarchikus, kevesebb ismétlés
  • ✅ Listák natív támogatása
  • ❌ Indentáció-érzékeny (tab vs szóköz hiba)
  • ❌ @PropertySource nem támogatja YAML-t

@ConfigurationProperties aktiválás

@Configuration
@EnableConfigurationProperties(DataSourceProperties.class)
public class AppConfig {
}

// VAGY: @ConfigurationPropertiesScan az alkalmazásosztályon
@SpringBootApplication
@ConfigurationPropertiesScan
public class MyApp {
    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }
}

Property validáció

@ConfigurationProperties(prefix = "app.mail")
@Validated
public class MailProperties {
    @NotBlank
    private String host;

    @Min(1) @Max(65535)
    private int port = 587;

    @Email
    private String from;

    // getterek és setterek
    public String getHost() { return host; }
    public void setHost(String host) { this.host = host; }
    public int getPort() { return port; }
    public void setPort(int port) { this.port = port; }
    public String getFrom() { return from; }
    public void setFrom(String from) { this.from = from; }
}

4. Kód példák

@Value vs @ConfigurationProperties

// @Value — egyedi property-k, egyszerű esetek
@Component
public class SimpleConfig {
    @Value("${app.name}")
    private String appName;

    @Value("${app.timeout:5000}")
    private long timeout;
}

// @ConfigurationProperties — csoportos binding, típusbiztos
@ConfigurationProperties(prefix = "app")
public class AppProperties {
    private String name;
    private long timeout = 5000;
    private final Security security = new Security();

    public static class Security {
        private String secret;
        private long tokenExpiry = 3600;
        // getterek + setterek
        public String getSecret() { return secret; }
        public void setSecret(String s) { this.secret = s; }
        public long getTokenExpiry() { return tokenExpiry; }
        public void setTokenExpiry(long t) { this.tokenExpiry = t; }
    }

    // getterek + setterek
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public long getTimeout() { return timeout; }
    public void setTimeout(long timeout) { this.timeout = timeout; }
    public Security getSecurity() { return security; }
}

Relaxed binding

A Spring Boot relaxed binding-ot használ:

# Mindegyik ugyanazt a property-t jelöli:
app.datasource.max-pool-size=10   # kebab-case (ajánlott)
app.datasource.maxPoolSize=10     # camelCase
app.datasource.max_pool_size=10   # underscore
APP_DATASOURCE_MAX_POOL_SIZE=10   # UPPER_CASE (env var)

Profil-specifikus bean-ek

@Configuration
public class DataSourceConfig {

    @Bean
    @Profile("dev")
    public DataSource devDataSource() {
        return new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.H2)
            .build();
    }

    @Bean
    @Profile("prod")
    public DataSource prodDataSource() {
        HikariDataSource ds = new HikariDataSource();
        ds.setJdbcUrl("jdbc:postgresql://prod-host/mydb");
        return ds;
    }
}

Környezeti változó → property mapping

# Shell / Docker
export SPRING_DATASOURCE_URL=jdbc:postgresql://prod/mydb
export SERVER_PORT=9090
export APP_SECURITY_SECRET=my-secret-key

Mapping szabály: UPPER_CASE + aláhúzás → lower.case + pont.

5. Trade-offok

Szempont @Value @ConfigurationProperties
Egyszerűség ✅ Gyors, egy property ❌ Több boilerplate
Típusbiztonság ❌ String-alapú, futásidejű hiba ✅ Compile-time típusok
Validáció ❌ Nincs beépített ✅ @Validated + JSR-303
IDE támogatás ❌ Korlátozott ✅ Autocomplete (metadata)
Csoportosítás ❌ Szétszórt ✅ Hierarchikus POJO
SpEL ✅ Támogatja ❌ Nem támogatja

Properties vs YAML

Szempont .properties .yml
Formátum Kulcs=érték Hierarchikus
Ismétlés Teljes prefix minden sornál Nincs ismétlés
Listák list[0]=a, list[1]=b - a + - b
@PropertySource ✅ Támogatja ❌ Nem támogatja
Hibalehetőség Alacsony Indentáció érzékeny

6. Gyakori hibák

❌ @Value SpEL hiba

// HIBA: $ helyett # → SpEL, nem property
@Value("#{server.port}")  // ← SpEL
private int port;

// HELYES:
@Value("${server.port}")  // ← property placeholder
private int port;

❌ Hiányzó property, nincs default

// HIBA: ha a property nem létezik → indulási hiba
@Value("${app.missing.property}")
private String value;

// HELYES: default érték
@Value("${app.missing.property:fallback}")
private String value;

❌ YAML indentáció hiba

# HIBA: tab karakter YAML-ben
spring:
    datasource:    # ← TAB volt itt! Hiba!
    url: jdbc:...

# HELYES: szóközök
spring:
  datasource:
    url: jdbc:...

❌ @ConfigurationProperties regisztráció hiánya

// HIBA: a properties osztály nem regisztrált → property-k null-ok
@ConfigurationProperties(prefix = "app")
public class AppProps { ... }

// HELYES: @EnableConfigurationProperties VAGY @ConfigurationPropertiesScan
@Configuration
@EnableConfigurationProperties(AppProps.class)
public class Config { }

❌ Property felülírás sorrendjének félreértése

A parancssori argumentum (--server.port=9090) mindig felülírja az application.properties értékét. A fejlesztők néha nem értik, miért nem érvényesül a fájlban beállított érték.

7. Mélyebb összefüggések

Config fájlok keresési sorrendje

A Spring Boot a következő helyeken keres config fájlokat:

  1. file:./config/ (projekt gyökér /config mappa)
  2. file:./config/*/ (almappák)
  3. file:./ (projekt gyökér)
  4. classpath:/config/ (classpath /config)
  5. classpath:/ (classpath gyökér)

spring.config.import (Boot 2.4+)

# Külső fájlok importálása
spring.config.import=optional:file:/etc/myapp/config.properties
spring.config.import=optional:configserver:http://config-server:8888

@ConfigurationProperties metadata

IDE autocomplete-hez generálj metaadatot:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

Ez META-INF/spring-configuration-metadata.json fájlt generál.

Immutable @ConfigurationProperties (record)

@ConfigurationProperties(prefix = "app.mail")
public record MailProperties(
    @NotBlank String host,
    @DefaultValue("587") int port,
    @Email String from
) {}

Constructor binding: nincs szükség setter-ekre, a record immutable.

Titkos adatok kezelése

# SOHA ne commitold a titkos adatokat!
# Használj környezeti változókat:
spring.datasource.password=${DB_PASSWORD}

# Vagy Spring Cloud Config + Vault
spring.config.import=vault://secret/myapp

8. Interjúkérdések

  1. Mi a különbség az application.properties és az application.yml között? Properties: kulcs=érték, YAML: hierarchikus indentáció. Properties támogatja a @PropertySource-t, YAML nem. YAML olvashatóbb, de indentáció-érzékeny.

  2. Mi a property source prioritás sorrendje? Parancssor > env var > profil-specifikus fájl > application.properties > default. A magasabb prioritás felülírja az alacsonyabbat.

  3. Mikor használj @Value-t és mikor @ConfigurationProperties-t? @Value: egyedi property-k, SpEL szükséges. @ConfigurationProperties: csoportos binding, validáció, IDE autocomplete, hierarchikus konfiguráció.

  4. Mi a relaxed binding? A Spring Boot automatikusan megérti a különböző formátumokat: max-pool-size = maxPoolSize = MAX_POOL_SIZE.

  5. Hogyan validálod a konfigurációs property-ket? @Validated + JSR-303 annotációk (@NotBlank, @Min, @Max, @Email) a @ConfigurationProperties osztályon.

  6. Mi a spring.config.import? Boot 2.4+ feature: külső fájlok, config server, vault importálása a property source-ba.

  7. Hogyan kezeled a titkos adatokat? Környezeti változók, Spring Cloud Config + Vault, Kubernetes secrets — soha ne commitold a property fájlba.

9. Szószedet

Fogalom Jelentés
Property source Konfigurációs értékek forrása (fájl, env var, parancssor)
@Value Egyedi property injektálás SpEL támogatással
@ConfigurationProperties Típusbiztos, csoportos property binding
Relaxed binding Automatikus formátum-felismerés (kebab, camel, upper)
Profile Környezet-specifikus konfiguráció (dev, prod, test)
BOM Bill of Materials — verzió management
spring.config.import Külső konfiguráció importálása (Boot 2.4+)
Configuration processor Annotation processor IDE metadata generáláshoz
Constructor binding Immutable @ConfigurationProperties (record, final fields)
Externalized configuration Az alkalmazás viselkedésének kódon kívüli vezérlése

10. Gyorsreferencia

# Property source prioritás (csökkenő):
# 1. --parancssor
# 2. SPRING_APPLICATION_JSON
# 3. OS env var (SERVER_PORT=9090)
# 4. application-{profile}.properties
# 5. application.properties
# 6. @PropertySource
# 7. SpringApplication.setDefaultProperties

# Profil aktiválás
spring.profiles.active=dev,metrics

# Config import (Boot 2.4+)
spring.config.import=optional:file:/etc/myapp/config.properties

# Relaxed binding
app.max-pool-size=10   # kebab (ajánlott .properties-ben)
APP_MAX_POOL_SIZE=10   # UPPER (env var)
// @Value — egyedi, SpEL
@Value("${app.name:default}")
private String name;

// @ConfigurationProperties — csoportos, típusbiztos
@ConfigurationProperties(prefix = "app")
@Validated
public class AppProps {
    @NotBlank private String name;
    @Min(1) private int port;
}

// Record binding (immutable)
@ConfigurationProperties(prefix = "app")
public record AppProps(@NotBlank String name, @DefaultValue("8080") int port) {}

🎮 Játékok

10 kérdés