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

Как конфигурировались параметры приложения на прошлой работе

1.0 Junior🔥 151 комментариев
#Soft Skills и карьера#Spring Framework

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

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

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

Конфигурирование параметров приложения

В профессиональной разработке конфигурирование параметров приложения требует системного подхода. Расскажу о практиках, которые я использовал на предыдущих проектах.

1. Иерархия конфигураций

Обычно структура выглядит так:

application.yml                    # основная конфиг (по умолчанию)
application-dev.yml               # разработка
application-test.yml              # тестирование
application-staging.yml           # staging
application-prod.yml              # production

SPRING_PROFILES_ACTIVE переменная окружения определяет, какой профиль загружается.

2. Структура конфигурации

application.yml:

spring:
  application:
    name: myapp
  datasource:
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
  jpa:
    hibernate:
      ddl-auto: validate
    properties:
      hibernate.dialect: org.hibernate.dialect.PostgreSQL13Dialect
  jackson:
    serialization:
      write-dates-as-timestamps: false

app:
  version: 1.0.0
  security:
    jwt:
      secret: ${JWT_SECRET}
      expiration: 86400000
  features:
    cache-enabled: true
    analytics-enabled: false

application-dev.yml:

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/myapp_dev
    username: postgres
    password: password
  jpa:
    hibernate:
      ddl-auto: create-drop
    show-sql: true
  level:
    org.springframework.web: DEBUG
    org.hibernate.SQL: DEBUG

app:
  features:
    analytics-enabled: true

application-prod.yml:

spring:
  datasource:
    url: ${DB_URL}
    username: ${DB_USER}
    password: ${DB_PASSWORD}
    hikari:
      maximum-pool-size: 50
      minimum-idle: 10
  jpa:
    hibernate:
      ddl-auto: validate
    show-sql: false
  level:
    root: WARN

app:
  features:
    cache-enabled: true
    analytics-enabled: true

3. Типизированные Properties классы

Использую @ConfigurationProperties для типизированного доступа:

@Configuration
@ConfigurationProperties(prefix = "app")
@Data
@Validated
public class AppProperties {
    @NotBlank
    private String version;
    
    private Security security;
    private Features features;
    
    @Data
    public static class Security {
        private Jwt jwt;
        
        @Data
        public static class Jwt {
            @NotBlank
            private String secret;
            
            @Positive
            private Long expiration;
        }
    }
    
    @Data
    public static class Features {
        private Boolean cacheEnabled = true;
        private Boolean analyticsEnabled = false;
    }
}

// Использование
@Component
public class TokenService {
    @Autowired
    private AppProperties appProperties;
    
    public String generateToken(String userId) {
        String secret = appProperties.getSecurity().getJwt().getSecret();
        long expiration = appProperties.getSecurity().getJwt().getExpiration();
        // ...
    }
}

4. Переменные окружения

Для production используются переменные окружения:

# Docker Compose
environment:
  SPRING_PROFILES_ACTIVE: prod
  SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/myapp
  SPRING_DATASOURCE_USERNAME: postgres
  SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD}
  JWT_SECRET: ${JWT_SECRET}
  DB_ENCRYPTION_KEY: ${DB_ENCRYPTION_KEY}

Dockerfile:

FROM openjdk:17-slim
WORKDIR /app
COPY target/myapp.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]

5. Vault для секретов

Для критичных данных используем HashiCorp Vault:

spring:
  cloud:
    vault:
      host: vault.example.com
      port: 8200
      scheme: https
      authentication: KUBERNETES
      kubernetes-path: kubernetes
      kubernetes-role: myapp
      kv:
        enabled: true
        version: 2
        backend: secret
@Configuration
public class VaultConfig {
    @Bean
    public PgpDecryptionService pgpDecryptionService(
            @Value("${vault.pgp.key}") String pgpKey) {
        return new PgpDecryptionService(pgpKey);
    }
}

6. Feature toggles

Для постепенного выката функций используем feature flags:

@Component
public class FeatureToggleService {
    @Autowired
    private AppProperties appProperties;
    
    public boolean isCacheEnabled() {
        return appProperties.getFeatures().getCacheEnabled();
    }
    
    public boolean isNewUIEnabled() {
        return appProperties.getFeatures().getNewUiEnabled();
    }
}

// Использование
@Service
public class UserService {
    @Autowired
    private FeatureToggleService toggleService;
    
    public User getUser(Long id) {
        if (toggleService.isCacheEnabled()) {
            return cacheService.getUser(id);
        }
        return userRepository.findById(id).orElseThrow();
    }
}

7. Конфигурирование Spring Security

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://auth.example.com
          jwk-set-uri: https://auth.example.com/.well-known/jwks.json
@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/v1/public/**").permitAll()
                .requestMatchers("/api/v1/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            )
            .oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> {}));
        return http.build();
    }
}

8. Database конфигурация

spring:
  datasource:
    url: ${DB_URL}
    hikari:
      maximum-pool-size: ${DB_POOL_SIZE:20}
      minimum-idle: ${DB_MIN_IDLE:5}
      connection-timeout: 30000
      idle-timeout: 600000
      max-lifetime: 1800000
  jpa:
    properties:
      hibernate:
        jdbc:
          batch_size: 20
          fetch_size: 50
        order_inserts: true
        order_updates: true

9. Logging конфигурация

logging:
  level:
    root: INFO
    com.mycompany: DEBUG
    org.springframework.web: WARN
    org.hibernate: WARN
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} - %msg%n"
    file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
  file:
    name: logs/application.log
    max-size: 10MB
    max-history: 30

10. CI/CD интеграция

# .gitlab-ci.yml
variables:
  SPRING_PROFILES_ACTIVE: test

test:
  script:
    - mvn clean test

deploy_staging:
  script:
    - |
      docker run -e SPRING_PROFILES_ACTIVE=staging \
        -e SPRING_DATASOURCE_URL=$DB_STAGING_URL \
        -e JWT_SECRET=$JWT_SECRET_STAGING \
        myapp:latest

deploy_prod:
  script:
    - |
      kubectl set env deployment/myapp \
        SPRING_PROFILES_ACTIVE=prod \
        SPRING_DATASOURCE_URL=$DB_PROD_URL \
        -n production

11. Лучшие практики

  1. Никогда не коммить secrets — используй переменные окружения
  2. Типизированные Properties — используй @ConfigurationProperties
  3. Профили для окружений — dev, test, staging, prod
  4. Валидация конфигурации — используй @Validated и constraints
  5. Feature toggles — для постепенного выката
  6. Документируй параметры — в README или wiki
  7. Default значения — для всех опциональных параметров
  8. Immutable конфигурация — не меняй во время работы
  9. Логируй значения конфигов при старте — для дебага
  10. Тестируй разные профили — убедись, что все работает

Этот подход обеспечивает гибкость, безопасность и удобство разработки и деплоя приложения.

Как конфигурировались параметры приложения на прошлой работе | PrepBro