Статьи

Мертвая простая конфигурация

Целые фреймворки были написаны с целью обработки конфигурации вашего приложения. Я предпочитаю более простой способ.

Если под конфигурацией мы подразумеваем « все, что может варьироваться в зависимости от развертывания », из этого следует, что мы должны постараться сохранить конфигурацию простой. В Java самым простым вариантом является простой файл свойств. Недостатком файла свойств является то, что вам нужно перезапустить приложение, когда вы хотите, чтобы оно приняло изменения. Или ты?

Вот простой метод, который я использовал в нескольких проектах:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class MyAppConfig extends AppConfiguration {
 
    private static MyAppConfig instance = new MyAppConfig();
 
    public static MyAppConfig instance() {
        return instance;
    }
 
    private MyAppConfig() {
        this("myapp.properties");
    }
 
    public String getServiceUrl() {
        return getRequiredProperty("service.url");
    }
 
    public boolean getShouldStartSlow() {
        return getFlag("start-slow", false);
    }
     
    public int getHttpPort(int defaultPort) {
        return getIntProperty("myapp.http.port", defaultPort);
    }
 
}

Класс AppConfiguration выглядит следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
public abstract class AppConfiguration {
 
    private static Logger log = LoggerFactory.getLogger(AppConfiguration.class);
 
    private long nextCheckTime = 0;
    private long lastLoadTime = 0;
    private Properties properties = new Properties();
    private final File configFile;
 
    protected AppConfiguration(String filename) {
        this.configFile = new File(filename);
    }
 
    public String getProperty(String propertyName, String defaultValue) {
        String result = getProperty(propertyName);
        if (result == null) {
            log.trace("Missing property {} in {}", propertyName, properties.keySet());
            return defaultValue;
        }
        return result;
    }
 
    public String getRequiredProperty(String propertyName) {
        String result = getProperty(propertyName);
        if (result == null) {
            throw new RuntimeException("Missing property " + propertyName);
        }
        return result;
    }
 
    private String getProperty(String propertyName) {
        if (System.getProperty(propertyName) != null) {
            log.trace("Reading {} from system properties", propertyName);
            return System.getProperty(propertyName);
        }
        if (System.getenv(propertyName.replace('.', '_')) != null) {
            log.trace("Reading {} from environment", propertyName);
            return System.getenv(propertyName.replace('.', '_'));
        }
 
        ensureConfigurationIsFresh();
        return properties.getProperty(propertyName);
    }
 
    private synchronized void ensureConfigurationIsFresh() {
        if (System.currentTimeMillis() < nextCheckTime) return;
        nextCheckTime = System.currentTimeMillis() + 10000;
        log.trace("Rechecking {}", configFile);
 
        if (!configFile.exists()) {
            log.error("Missing configuration file {}", configFile);
        }
 
        if (lastLoadTime >= configFile.lastModified()) return;
        lastLoadTime = configFile.lastModified();
        log.debug("Reloading {}", configFile);
 
        try (FileInputStream inputStream = new FileInputStream(configFile)) {
            properties.clear();
            properties.load(inputStream);
        } catch (IOException e) {
            throw new RuntimeException("Failed to load " + configFile, e);
        }
    }
}

Это считывает файл конфигурации эффективным способом и обновляет настройки по мере необходимости. Он поддерживает переменные среды и системные свойства по умолчанию. И это даже дает довольно хороший журнал того, что происходит.

  • Полный исходный код и волшебный источник данных, который обновляется автоматически, см. В этом гисте: https://gist.github.com/jhannes/b8b143e0e5b287d73038

Наслаждайтесь!

Ссылка: Полная простая конфигурация от нашего партнера по JCG Йоханнеса Бродвола из блога Thinking Inside a Bigger Box .