Как реализовать политику переопределения свойств с помощью rocoto? - PullRequest
2 голосов
/ 06 марта 2012

Я хотел бы реализовать политику свойств в моем приложении: я хочу определить свойства по умолчанию внутри моего приложения, и в случае, я хочу сохранить возможность переопределения этих параметров по умолчанию конфигурационным файлом вне файла war.

Поэтому я определяю ConfigModule.java:

public class ConfigModule extends AbstractModule {

    private static final Logger LOG = LoggerFactory.getLogger(BatchConfigModule.class);

    @Override
    protected void configure() {

        LOG.info("Start rocoto configuration");
        Module rocotoModule = Rocoto.expandVariables(new ConfigurationModule() {
            @Override
            protected void bindConfigurations() {
                // default config
                LOG.debug("Default config");
                bindProperties(Config.DEFAULT_CONFIG);
                LOG.debug("before config.properties");
                // // For overriding default config
                File propertiesFile = new File(Resources.getResource("config.properties")
                        .getFile());
                if (propertiesFile.exists()) {
                    LOG.info("config.properties was found in classpath: ["
                            + propertiesFile.getAbsolutePath() + "]");
                    bindProperties(propertiesFile);
                } else {
                    LOG.info("config.properties was not found in classpath");
                }
            }
        });
        install(rocotoModule);

    }
}

Config.DEFAULT_CONFIG расширяет java.util.Properties и определяет свойства по умолчанию, каждый из параметров в DEFAULT_CONFIG выглядит следующим образом =>

DEFAULT_CONFIG.setProperty("testModeInt", "${testMode|false}");

И я вставляю в свой код свойства @Named ("testModeInt").

Моя проблема в том, что если мои config.properties отсутствуют в classpath, у меня есть ошибка:

Caused by: java.lang.IllegalStateException: Re-entry not allowed
    at com.google.inject.internal.util.$Preconditions.checkState(Preconditions.java:142)
    at org.nnsoft.guice.rocoto.configuration.ConfigurationModule.configure(ConfigurationModule.java:63)
    at com.google.inject.AbstractModule.configure(AbstractModule.java:59)
    at com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:223)
    at com.google.inject.spi.Elements.getElements(Elements.java:101)
    at com.google.inject.spi.Elements.getElements(Elements.java:92)
    at com.google.inject.util.Modules$RealOverriddenModuleBuilder$1.configure(Modules.java:152)
    at com.google.inject.AbstractModule.configure(AbstractModule.java:59)
    at com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:223)
    at com.google.inject.AbstractModule.install(AbstractModule.java:118)
    at net.antoine.ConfigModule.configure(ConfigModule.java:51)

Что я просто не понимаю, откуда эта проблема,или может эта реализация не хороша, другая идея?

1 Ответ

0 голосов
/ 27 января 2013

Вы можете попробовать OWNER API : он поддерживает 3 уровня переопределения свойств, а также обеспечивает сопоставление между объектом Java и файлами свойств и другими полезными функциями.

Первая возможность переопределенияявляется спецификацией значения по умолчанию для интерфейса отображения:

public interface ServerConfig extends Config {
    @DefaultValue("42")
    int maxThreads();
}

ServerConfig по умолчанию сопоставляется с ServerConfig.properties в том же пакете.Если свойство «maxThreads» не указано, то по умолчанию используется значение 42 (файлы свойств переопределяют DefaultValue).

Вторая возможность переопределения - это возможность указать несколько местоположений файлов свойств для класса, поэтомупервый найденный ресурс используется.Таким образом, вы определяете внутренние свойства в вашем jar-файле и позволяете пользователю указать файл переопределяющих свойств в его домашнем каталоге или в / etc / myapp, или везде, где вы предпочитаете:

@Sources({ "file:~/.myapp.config", 
           "file:/etc/myapp.config", 
           "classpath:foo/bar/baz.properties" })
public interface ServerConfig extends Config {

    @Key("server.http.port")
    int port();

    @Key("server.host.name")
    String hostname();

    @Key("server.max.threads");
    @DefaultValue("42")
    int maxThreads();
}

Третье переопределениеМожно указать, что вы хотите, чтобы все вышеперечисленные файлы были рассмотрены, но вы хотите, чтобы переопределение происходило на уровне свойств, поэтому, если все вышеуказанные файлы свойств доступны, при запросе свойства maxThreads() это будетсначала выполняется поиск в file:~/.myapp.config - если не найден - затем в file:/etc/myapp.config, а затем в classpath:foo/bar/baz.properties, и, в крайнем случае, применяется @DefaultValue("42"), затем вы указываете библиотеке, что она должна произвести слияние из всех ресурсов свойств (и рассмотрим их все)

@LoadPolicy(LoadType.MERGE)
@Sources({ "file:~/.myapp.config", 
           "file:/etc/myapp.config", 
           "classpath:foo/bar/baz.properties" })
public interface ServerConfig extends Config {
    // same content as above.
}
...