В большинстве проектов Java/Java EE существует общее требование, касающееся того, как различать конфигурации среды, такие как разработка, тестирование, контроль качества, производство и т.д. по этой причине существует множество фреймворков или библиотек для решения этой проблемы:
- Конфигурация дельтаспайка
- Конфигурация Apache Commons
- Сабо
- Апачи Тамайя
- Конфигурация Dropwizard
- Формат данных Джексона YAML
Даже есть предложение по запросу спецификации Java (JSR):
Как эти библиотеки решают проблему
Большинству из этих библиотек требуется иметь точку (точки) внедрения для конфигураций, а также источник (ы) конфигурации (ов), что-то вроде этого:
dev.свойства :
host=localhost port=5432 schema=public
prod.свойства :
host=production.com port=5432 schema=public
ConfigurationResolver.java :
class ConfigurationResolver implements SomeLibraryInterface {
@Override
public String resolvePropertyFilename() {
// probably do some trick to load a global/base configuration
// if is not provided for the library
return String.format("%s.properties", System.getProperty("MY_ENV", "dev"));
}
}
MyType.java :
class MyType {
@Configuration(key = "host")
String host;
@Configuration(key = "port")
int port;
@Configuration(key = "schema", defaultValue = "public")
String schema;
}
Обратите внимание, что вся детализация необходима только из-за отсутствия поддержки пользовательских типов
Кроме того, благодаря новым возможностям Java 8, в частности с помощью методов default и некоторых служебных классов, легко добиться такого поведения.
С помощью методов Java 8 по умолчанию
Конфигурация по умолчанию.java :
interface DefaultConfiguration {
default DataSource datasource {
// create the DS with host, port and schema
return new MyDataSource("localhost", 5432, "public");
}
}
Конфигурация устройства.java :
class DevConfiguration implements DefaultConfiguration {
// No need to override methods if they are the same
}
Конфигурация Prod :
class ProdConfiguration implements DefaultConfiguration {
default DataSource datasource {
return new MyDataSource("production.com", 5432, "public");
}
}
ConfigurationFactory.java :
abstract class ConfigurationFactory {
private static final Map configurations = new HashMap<>();
static {
configurations.put("development", new DevConfiguration());
configurations.put("production", new ProdConfiguration());
}
public static DefaultConfiguration configuration() {
return configurations.getOrDefault(System.getProperty("MY_ENV"), new DevConfiguration());
}
}
Обратите внимание, что вы можете использовать перечисление вместо карты в качестве фабрики конфигурации.
Плюсы
- Безопасные для типов конфигурации
- Поддержка всех видов типов, а не только
String,Датаили примитивы. вы можете указать или примерИсточник данных,Временные единицы,JedisPoolи т.д. - Нет преобразования/сопоставления строк с типами
- Больше нет
.свойства,.xmlили.ymlфайлы - Возможность использовать другие источники для заполнения свойств, таких как файлы свойств, база данных, rest API и т.д.
- В вашем приложении не требуется библиотека/фреймворк/зависимость
Аферы
- Изменения в конфигурации требуют компиляции/развертывания (это не должно быть проблемой в 99% случаев)
исходный код
Оригинал: “https://dev.to/cchacin/java-8-type-safe-configuration-with-default-methods-587i”