我想在我的应用程序中实现属性策略:我想在我的应用程序中定义默认属性,并且在我的情况下,我希望保留通过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)
我只是不明白,这个问题来自哪里,或者这个实现可能不好,另一个想法?
答案 0 :(得分:0)
您可以尝试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.
}