Ответ
В Spring доступ к переменным окружения и свойствам приложения предоставляет интерфейс org.springframework.core.env.Environment. Это центральный абстракция для работы с конфигурацией.
Основные способы доступа:
-
Инъекция через
@Autowired:@Component public class MyService { @Autowired private Environment env; public void someMethod() { String dbUrl = env.getProperty("database.url"); int port = env.getProperty("server.port", Integer.class, 8080); // Значение по умолчанию boolean isFeatureEnabled = env.getProperty("feature.flag", Boolean.class, false); } } -
Использование
@Value:@Component public class MyComponent { // Получение значения свойства @Value("${api.key}") private String apiKey; // Со значением по умолчанию @Value("${cache.ttl:3600}") private int cacheTtl; // Получение переменной окружения ОС @Value("${JAVA_HOME}") private String javaHome; }
Источники свойств (PropertySources): Spring загружает свойства из различных источников в определенном порядке (поздние переопределяют ранние):
- Аргументы командной строки (
--server.port=9090). - Переменные окружения ОС (
JAVA_HOME,DATABASE_URL). - Файлы свойств из
application-{profile}.properties/.yml. - Файл
application.properties/.yml. - Аннотация
@PropertySource.
Пример работы с профилями:
@Configuration
public class AppConfig {
@Autowired
Environment env;
@Bean
public DataSource dataSource() {
// Создание бина в зависимости от активного профиля
if (env.acceptsProfiles(Profiles.of("prod"))) {
return createProductionDataSource();
} else {
return createEmbeddedDataSource();
}
}
// Проверка наличия свойства
public boolean isPropertySet(String key) {
return env.containsProperty(key);
}
}
Практические рекомендации:
- Конфиденциальные данные: Храните пароли, API-ключи в переменных окружения, а не в файлах конфигурации, которые могут попасть в репозиторий.
- 12-факторное приложение: Использование переменных окружения — один из ключевых принципов для конфигурации, зависящей от среды (dev, staging, prod).
- Docker/Kubernetes: Конфигурация через
env:в Docker Compose или ConfigMaps/Secrets в Kubernetes идеально ложится на эту модель Spring.
Ответ 18+ 🔞
А, ну ты про эту хуйню, про конфиги в Спринге! Слушай, тут всё просто, как три копейки, но если не знать — можно ебучу словить. Так вот, есть у них там такая штука — Environment. Это типа главный занюха в мире настроек твоего приложения, знает всё: от порта сервера до того, какой пароль у твоего продакшен-постгреса.
Как к нему подъебаться:
-
Воткнуть напрямую, по-пацански (
@Autowired):@Component public class MyService { @Autowired private Environment env; // Взял и впендюрил public void someMethod() { // Тянешь свойство, как из кармана String dbUrl = env.getProperty("database.url"); // А если свойства нет — подставляем дефолт, чтоб не вылетало в пизду int port = env.getProperty("server.port", Integer.class, 8080); boolean isFeatureEnabled = env.getProperty("feature.flag", Boolean.class, false); } } -
Через аннотацию
@Value— для ленивых и точечных:@Component public class MyComponent { // Просто говоришь — дай сюда api.key, и оно прилетает @Value("${api.key}") private String apiKey; // А если в конфигах пусто, то будет 3600. Красота, блядь. @Value("${cache.ttl:3600}") private int cacheTtl; // И даже системные переменные ОС вытащить можно, вот же ж хитрая жопа! @Value("${JAVA_HOME}") private String javaHome; }
Откуда эта тварь свойства берёт? (Источники, они же PropertySources) Тут, блядь, чёткая иерархия, как в армии: кто последний пришёл, тот и прав. Источники грузятся в порядке, и поздние перебивают ранние:
- Аргументы командной строки (типа
--server.port=9090). Самый крутой пацан, всех перебивает. - Переменные окружения ОС (
JAVA_HOME,DATABASE_URL). - Файлы профилей (
application-prod.properties). - Главный файл (
application.properties). - Что ты там ещё через
@PropertySourceнаколхозил.
Пример с профилями, чтобы не облажаться на продакшене:
@Configuration
public class AppConfig {
@Autowired
Environment env; // Наш чёрный ящик
@Bean
public DataSource dataSource() {
// Спрашиваем: "Чувак, мы на проде?"
if (env.acceptsProfiles(Profiles.of("prod"))) {
return createProductionDataSource(); // Да? Тогда серьёзную базу давай
} else {
return createEmbeddedDataSource(); // Нет? Ну хуй с ним, H2 сойдёт
}
}
// Простая проверка: а есть ли такое свойство вообще, или я уже брежу?
public boolean isPropertySet(String key) {
return env.containsProperty(key);
}
}
Жизненные советы, чтобы не было мучительно больно:
- Пароли, ключи, секреты: Ты что, охуел? В файлы
application.propertiesи в гит их пихать? Только переменные окружения, ёпта! Или специальные vault'ы. Иначе потом будешь плакать, как Герасим над Муму. - 12-факторное приложение: Это не просто модное словечко. Конфиг через переменные окружения — это святое. Один бинарник, а поведение меняется в зависимости от среды (dev, staging, prod). Красота.
- Docker/Kubernetes: Тут эта модель просто пиздец как хорошо ложится. В Docker Compose пишешь
environment:, в кубере — ConfigMaps да Secrets, и твоё приложение даже не заметит подмены. Как будто так и было задумано.