← Назад к вопросам

Откуда Spring может загружать Property

2.2 Middle🔥 121 комментариев
#Spring Framework

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Источники загрузки Properties в Spring

Properties - это конфигурационные параметры приложения (БД URL, порты, API ключи и т.д.). Spring имеет мощный механизм Environment и PropertyResolver, который позволяет загружать конфигурацию из множества источников с определенным порядком приоритета.

1. application.properties / application.yml

Основной способ - файлы в resources директории.

# resources/application.properties
server.port=8080
server.servlet.context-path=/api

spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=admin
spring.datasource.password=secret123

spring.jpa.hibernate.ddl-auto=validate
spring.jpa.show-sql=false

app.name=MyApplication
app.version=1.0.0
app.timezone=Europe/Moscow

Или в YAML формате:

# resources/application.yml
server:
  port: 8080
  servlet:
    context-path: /api

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/mydb
    username: admin
    password: secret123
  jpa:
    hibernate:
      ddl-auto: validate
    show-sql: false

app:
  name: MyApplication
  version: 1.0.0
  timezone: Europe/Moscow

2. Profile-specific Properties

Различные конфигурации для разных окружений.

resources/
  application.properties      # Default
  application-dev.properties  # Development
  application-test.properties # Testing
  application-prod.properties # Production
# application-dev.properties
server.port=8080
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb_dev
logging.level.root=DEBUG

# application-prod.properties
server.port=8080
spring.datasource.url=jdbc:postgresql://prod-db.example.com:5432/mydb
logging.level.root=WARN

Активировать профиль:

# Via command line
java -jar app.jar --spring.profiles.active=prod

# Via environment variable
export SPRING_PROFILES_ACTIVE=prod
java -jar app.jar

# Via application.properties
spring.profiles.active=prod

3. Environment Variables

Spring автоматически загружает переменные окружения.

# Установить переменные
export SERVER_PORT=9090
export SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/mydb
export SPRING_DATASOURCE_USERNAME=admin

# Запустить приложение
java -jar app.jar

Конвенция именования:

  • Property: server.port -> Env var: SERVER_PORT
  • Property: spring.datasource.url -> Env var: SPRING_DATASOURCE_URL
  • Подчеркивание заменяет точку, UPPERCASE

В коде:

@RestController
public class ConfigController {
  
  @Value("${server.port}")
  private int serverPort;
  
  @Value("${spring.datasource.url}")
  private String dbUrl;
  
  @GetMapping("/config")
  public Map<String, Object> getConfig() {
    return Map.of(
      "serverPort", serverPort,
      "dbUrl", dbUrl
    );
  }
}

4. System Properties

Java System properties (-D флаги).

# При запуске
java -Dserver.port=9090 -Dapp.mode=production -jar app.jar

В коде:

@Component
public class SystemPropertyConfig {
  
  @Value("${server.port}")
  private int port;
  
  @Value("${app.mode}")
  private String mode;
  
  public void init() {
    System.out.println("Port: " + port);
    System.out.println("Mode: " + mode);
  }
}

5. application-*.properties в разных местах

Spring ищет properties в разных местах с приоритетом:

1. classpath:application.properties (самый низкий)
2. classpath:application-{profile}.properties
3. file:./application.properties
4. file:./application-{profile}.properties (самый высокий)
5. Environment variables (переопределяет файлы)
6. System properties (самый высокий приоритет)

6. Custom Properties файлы

Использование своих файлов конфигурации.

@Configuration
@PropertySource("classpath:custom.properties")
public class CustomPropertyConfig {
  
  @Value("${custom.value}")
  private String customValue;
}

С плейсхолдерами:

@Configuration
@PropertySource({
  "classpath:app.properties",
  "classpath:app-${spring.profiles.active}.properties"  // Динамический
})
public class MultiPropertyConfig {
  // ...
}

7. @ConfigurationProperties класс

Элегантный способ загрузки группы свойств.

# application.properties
app.name=MyApp
app.version=1.0.0
app.features.auth=true
app.features.cache=true

db.primary.url=jdbc:postgresql://localhost:5432/main
db.primary.username=admin
db.secondary.url=jdbc:postgresql://localhost:5432/replica
db.secondary.username=reader
@Configuration
@ConfigurationProperties(prefix = "app")
public class AppProperties {
  
  private String name;
  private String version;
  private Features features = new Features();
  
  // Getters и setters
  public static class Features {
    private boolean auth;
    private boolean cache;
    
    // Getters и setters
  }
}

@Configuration
@ConfigurationProperties(prefix = "db")
public class DatabaseProperties {
  
  private Map<String, DataSourceConfig> configs = new HashMap<>();
  
  public static class DataSourceConfig {
    private String url;
    private String username;
    
    // Getters и setters
  }
}

// Использование
@Service
public class MyService {
  
  @Autowired
  private AppProperties appProps;
  
  @Autowired
  private DatabaseProperties dbProps;
  
  public void init() {
    System.out.println("App: " + appProps.getName());
    System.out.println("Primary DB: " + dbProps.getConfigs().get("primary").getUrl());
  }
}

8. Environment API

Программный доступ к properties.

@Service
public class ConfigService {
  
  @Autowired
  private Environment env;
  
  public void printAllProperties() {
    // Получить значение с default
    String port = env.getProperty("server.port", "8080");
    System.out.println("Port: " + port);
    
    // Получить значение с преобразованием
    Integer maxConnections = env.getProperty(
      "db.max-connections",
      Integer.class,
      10
    );
    System.out.println("Max connections: " + maxConnections);
    
    // Проверить есть ли property
    boolean isProduction = env.containsProperty("app.production");
    
    // Получить active profiles
    String[] profiles = env.getActiveProfiles();
    System.out.println("Active profiles: " + Arrays.toString(profiles));
  }
}

9. Docker переменные

Для контейнеризованных приложений.

# Dockerfile
FROM openjdk:17-slim
COPY app.jar /app/app.jar

ENV SERVER_PORT=8080
ENV SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/mydb
ENV SPRING_DATASOURCE_USERNAME=admin
ENV LOGGING_LEVEL_ROOT=INFO

CMD ["java", "-jar", "/app/app.jar"]
# docker-compose.yml
version: '3.8'
services:
  app:
    build: .
    environment:
      - SERVER_PORT=8080
      - SPRING_DATASOURCE_URL=jdbc:postgresql://postgres:5432/mydb
      - SPRING_DATASOURCE_USERNAME=admin
      - SPRING_DATASOURCE_PASSWORD=secret
      - SPRING_PROFILES_ACTIVE=prod
    ports:
      - "8080:8080"
    depends_on:
      - postgres
  postgres:
    image: postgres:15
    environment:
      - POSTGRES_DB=mydb
      - POSTGRES_USER=admin
      - POSTGRES_PASSWORD=secret

10. Kubernetes ConfigMap и Secrets

# ConfigMap для non-secret properties
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  application.properties: |
    server.port=8080
    app.name=MyApp
    logging.level.root=INFO

---
# Secret для sensitive данных
apiVersion: v1
kind: Secret
metadata:
  name: app-secrets
type: Opaque
stringData:
  spring.datasource.password: secret123
  app.api.key: xyz789

---
# Pod использует ConfigMap и Secret
apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  containers:
  - name: app
    image: myapp:latest
    envFrom:
    - configMapRef:
        name: app-config
    - secretRef:
        name: app-secrets

11. Spring Cloud Config Server

Для централизованного управления конфигурацией.

# application.yml
spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/myorg/config-repo
          default-label: main
// Client side
@SpringBootApplication
@EnableConfigClient
public class ConfigClientApp {
  public static void main(String[] args) {
    SpringApplication.run(ConfigClientApp.class, args);
  }
}

@Service
@RefreshScope  // Обновляется при POST /actuator/refresh
public class MyService {
  
  @Value("${app.property:default}")
  private String property;
}

12. Порядок приоритета (от выше к ниже)

  1. System properties (-D флаги)
  2. Environment variables (переменные ОС)
  3. Config Server (Spring Cloud)
  4. application.properties файлы:
    • файлы вне JAR (file://)
    • файлы в JAR (classpath://)
  5. Default values (в @Value или @ConfigurationProperties)

Best Practices

  1. Используй @ConfigurationProperties для группы свойств
  2. Никогда не коммить passwords - используй переменные окружения
  3. Профилируй конфигурацию для разных окружений
  4. Валидируй properties с @Validated и @ConfigurationProperties
  5. Документируй properties - добавь комментарии
  6. Используй Environment для runtime проверок - гибче чем статические значения
// Пример с валидацией
@Configuration
@ConfigurationProperties(prefix = "app")
@Validated
public class ValidatedConfig {
  
  @NotBlank(message = "App name is required")
  private String name;
  
  @Positive(message = "Port must be positive")
  private int port;
  
  @Email(message = "Admin email must be valid")
  private String adminEmail;
  
  // Getters и setters
}

Spring предоставляет огромное количество способов для конфигурирования приложения, что позволяет адаптировать его к любому окружению без изменений кода!