Java 如何使用rocoto实现覆盖属性策略?

Java 如何使用rocoto实现覆盖属性策略?,java,properties,guice,Java,Properties,Guice,我想在我的应用程序中实现属性策略:我想在我的应用程序中定义默认属性,在这种情况下,我想保留通过war文件之外的配置文件重写此默认参数的可能性 因此,我定义了一个ConfigModule.java: public class ConfigModule extends AbstractModule { private static final Logger LOG = LoggerFactory.getLogger(BatchConfigModule.class); @Overr

我想在我的应用程序中实现属性策略:我想在我的应用程序中定义默认属性,在这种情况下,我想保留通过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\u Config扩展了java.util.Properties并定义了默认属性,默认配置中的每个参数如下=>

DEFAULT_CONFIG.setProperty("testModeInt", "${testMode|false}");
我将@NamedtestModeInt注入我的代码属性

我的问题是,如果我的config.properties不在类路径中,我有一个错误:

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)
我只是不明白,这个问题是从哪里来的,或者可能这个实现不好,另一个想法

您可以尝试:它支持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时,将首先在文件:~/.myapp.config-如果找不到-然后在文件:/etc/myapp.config中搜索,然后在类路径:foo/bar/baz.properties中搜索,最后应用@DefaultValue42,然后,向库指定它必须生成所有属性资源的合并,并将它们全部考虑为

@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.
}
您可以尝试:它支持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时,将首先在文件:~/.myapp.config-如果找不到-然后在文件:/etc/myapp.config中搜索,然后在类路径:foo/bar/baz.properties中搜索,最后应用@DefaultValue42,然后,向库指定它必须生成所有属性资源的合并,并将它们全部考虑为

@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.
}