将配置绑定到guice中的名称递归

时间:2015-05-18 18:05:15

标签: configuration jackson guice dropwizard

我的应用程序具有使用Jackson的rapidxml注释将注释解析为文件而加载的配置。例如:

public class RootConfiguration extends Configuration {

  @JsonProperty
  @NotEmpty
  public String foo;

  @JsonProperty
  public BarConfiguration bar;

  public class BarConfiguration extends Configuration {
    @JsonProperty
    public String baz;      
  }
}

然后将配置注入我的Module中的提供程序,以帮助我将这些属性绑定到使用它们的代码中的位置。像这样:

  @Provides
  @Named("config")
  public RootConfiguration provideRootConfiguration(RootConfiguration configuration) {
    return configuration;
  }

  @Provides
  @Named("config.foo")
  public String provideFooConfiguration(RootConfiguration configuration) {
    return configuration.foo;
  }

  @Provides
  @Named("config.bar")
  public BarConfiguration provideBarConfiguration(RootConfiguration configuration) {
    return configuration.bar;
  }

等等。

我正在寻找一个框架来帮助我避免这种繁琐的工作。

我会想象看起来像这样的东西:

@Configuration(value = "config", bindSubProperties = true)
public class RootConfiguration extends Configuration {
...

那将使用Reflection将我的类中的任何子字段绑定为guice Names。 我查看了Governator的配置注释,但据我所知,它们需要应用于我想要绑定的每个配置,这节省了一些编码,但基本上是相同的(我仍然必须手动指定我想要绑定的每个配置的路径。

在我推出自己的实现之前,有什么能够满足我需要的东西吗?

注意:我正在将此用于Dropwizard项目,因此使用Jackson将配置映射到POJO的约束相当紧张(除非我将应用程序配置移到配置yaml之外)。

1 个答案:

答案 0 :(得分:1)

我不知道有任何工具会为你做这件事,但是你可以用这样的东西很容易地做到这一点:

void bindConfiguration() {
    for (Field field : RootConfiguration.class.getFields() {
        bindConfiguration(TypeLiteral.get(field.getGenericType()), field);
    }
}

<T> void bindConfiguration(TypeLiteral<T> type, Field field) {
    bind(type)
            .annotatedWith(Names.named("config." + field.getName()))
            .toProvider(new ConfigurationProvider<T>(field))
            .in(Singleton.class);
}

class ConfigurationProvider<T> implements Provider<T> {
    private final Field field;
    @Inject RootConfiguration configuration;

    ConfigurationProvider(Field field) {
        this.field = field;
    }

    @Override
    public T get() {
        return (T) field.get(configuration);
    }
}