【发布时间】:2016-07-26 12:29:07
【问题描述】:
我的总体目标是从属性文件加载属性,然后将这些属性注入到我的对象中。我还想使用这些属性来使用 Guice 实例化某些单例类。我的单例类如下所示:
public class MainStore(){
private String hostname;
@Inject
public void setHostname(@Named("hostname") String hostname){
this.hostname = hostname;
}
public MainStore(){
System.out.println(hostname);
}
}
我正在尝试使用此提供程序实例化一个单例:
public class MainStoreProvider implements Provider<MainStore> {
@Override
public MainStore get(){
MainStore mainStore = new MainStore();
return mainStore;
}
}
我的 configurationModule 是一个从运行时指定的属性文件加载配置的模块:
public class ConfigurationModule extends AbstractModule {
@Override
protected void configure(){
Properties properties = loadProperties();
Names.bindProperties(binder(), properties);
}
private static Properties loadProperties() {
String resourceFileName = "example.properties";
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream inputStream = classLoader.getResourceAsStream(resourceFileName);
Properties properties = new Properties();
properties.load(inputStream);
return properties;
}
}
我的 example.properties 文件包含:
hostname = testHostName
然后当我需要我正在使用的 MainStore 单例时:
Injector injector = Guice.createInjector(new ConfigurationModule());
MainStoreProvider mainStoreProvider = injector.getInstance(MainStoreProvider.class);
MainStore mainStore = mainStoreProvider.get(); //MainClass singleton
这是正确的下坡路吗?我应该以完全不同的方式来做这件事吗?为什么我的 MainStore 没有打印出正确的主机名?
【问题讨论】:
-
您的提供商未设置主机名属性。为什么首先需要提供者?由于 guice 没有处理你的类构造,它不会设置属性。您必须将您的属性注入您的提供程序实现并在创建后设置它。另外,如果我错了,请纠正我,但是您的 Provider 不会创建单例,而是每次都创建一个新实例。
-
我想使用提供者为我提供单例。我不知道该怎么做,所以我可能做错了。我还认为 Guice 会将我的 Injected 属性级联到提供程序中创建的所有类中。不过,这种方法可能是完全错误的。
-
不,guice 不会为您这样做,因为您是创建对象的人,而不是 guice。您的主机名打印错误的原因也是因为您在构造函数中打印它,但是您注入了一个方法。方法注入只能在构造对象之后发生(因为没有方法可以调用)。如果你想要一个单例,那么你可以在单例范围内绑定,并简单地用属性注入构造函数(就像你做方法一样)。将您的属性视为一个命名字符串对象,您可以将其注入到任何 Guice 托管类中。
标签: java dependency-injection singleton guice properties-file