Откуда Spring может загружать Property
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Источники загрузки 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. Порядок приоритета (от выше к ниже)
- System properties (-D флаги)
- Environment variables (переменные ОС)
- Config Server (Spring Cloud)
- application.properties файлы:
- файлы вне JAR (file://)
- файлы в JAR (classpath://)
- Default values (в @Value или @ConfigurationProperties)
Best Practices
- Используй @ConfigurationProperties для группы свойств
- Никогда не коммить passwords - используй переменные окружения
- Профилируй конфигурацию для разных окружений
- Валидируй properties с @Validated и @ConfigurationProperties
- Документируй properties - добавь комментарии
- Используй 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 предоставляет огромное количество способов для конфигурирования приложения, что позволяет адаптировать его к любому окружению без изменений кода!