将值绑定到Guice中的两种可能性之一

时间:2014-06-12 20:44:06

标签: java guice

假设我有一个默认值,如果设置了System.getProperty("foo"),则可以覆盖该值。我有一个模块,我有

bindConstant().annotatedWith(Names.named("Default foo")).to(defaultValue);

我想知道实现一个模块的最佳方法是什么,我希望将带有“foo”注释的内容绑定到System.getProperty("foo"),或者,如果它不存在,则绑定“Default foo”绑定。< / p>

我想到了一个像这样的简单模块:

public class SimpleIfBlockModule extends AbstractModule {
    @Override
    public void configure() {
        requireBinding(Key.get(String.class, Names.named("Default foo")));
        if (System.getProperties().containsKey("foo")) {
            bindConstant().annotatedWith(Names.named("foo")).to(System.getProperty("foo"));
        } else {
            bind(String.class).annotatedWith(Names.named("foo")).to(Key.get(String.class, Names.named("Default foo")));
        }
    }
}

我还考虑过创建一个“系统属性模块”:

public class SystemPropertyModule extends PrivateModule {
    @Override
    public void configure() {
        Names.bindProperties(binder(), System.getProperties());
        if (System.getProperties().contains("foo")) {
            expose(String.class).annotatedWith(Names.named("foo"));
        }
    }
}

使用SystemPropertyModule创建一个第三个模块的注入器,它执行“foo”的绑定。这两个似乎都有它们的缺点,所以我想知道是否有什么我应该做的不同。我希望有一些东西既可以无注射器,也可以合理地推广到多个“foo”属性。有什么想法吗?

1 个答案:

答案 0 :(得分:3)

如果您不需要在运行时更改绑定,那么您的第一个设计对我来说似乎是最好的选择(即,从注入器创建时起,绑定是不变的)。

对于您在运行时决定的任何值,您需要提供者或@Provides方法:

public class SimpleIfBlockModule extends AbstractModule {
    @Override public void configure() { }

    @Provides @Named("foo") String provideFoo(
             @Named("Default foo") String defaultFoo,
             AnyInjectableDependencyHere ifNeeded) {
        if (System.getProperties().containsKey("foo")) {
            return System.getProperty("foo");
        } else {
            return defaultFoo;
        }
    }
}

如果您需要在运行时根据参数use this solution确定。