2012-03-06 49 views
2

我想在我的应用程序中实现属性策略:我想要在我的应用程序中定义默认属性,并且,我想保留覆盖war文件之外的配置文件的默认参数的可能性。如何使用rocoto实现覆盖属性策略?

所以我定义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不存在在类路径中,我有一个错误:

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

您可以试试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. 
}