我有一个名为Legacy的现有类,它主要用旧式单例模式编写。现在我想向它介绍一个新领域,我想使用Guice。 Legacy本身不受Guice控制,它由另一个Service类使用(在Service类内部,它调用Legacy类的getInstance()来立即检索Legacy对象),并且使用Guice注入器创建了Service类。 / p>
public class Legacy {
public synchronized static Legacy getInstance() {
if(sInstance == null) {
sInstance = new Legacy();
}
return sInstance;
}
private Legacy() {
legacyObj = LegacyField.getInstance(); // get a singleton
}
private static Legacy sInstance;
private LegacyField legacyObj;
private NewField newObj; // this is the new dependency I would like to add using Guice
}
我尝试的是我尝试将方法Inject放入Legacy类
@Inject
public void setNewField(NewField newObj) {
this.newObj = newObj;
}
在Service的模块文件中,我绑定了NewField对象,但是当我运行该程序时,它抛出了一个NullPointer异常。所以注入不起作用。有没有想过如何让NewField注入我的程序,但保持当前的老派单身范式,而不是对其他一切做太多改变?
修改 下面至少有三个解决方案,我不太清楚哪个是最好的,或者它们是否相同。
答案 0 :(得分:3)
我刚刚找到另一个解决方案:
// put in the module
bind(Legacy.class).toInstance(Legacy.getInstance());
在此示例中,您的模块本身(而不是Guice)负责获取Legacy实例,然后要求Guice始终使用此单个实例来完成所有Legacy注入请求。 但根据javadoc 创建Injector时,它将自动为此实例执行字段和方法注入,但Legacy上的任何可注入构造函数都将被忽略。请注意,使用此方法会导致无法控制的“急切加载”行为。
答案 1 :(得分:2)
虽然只比Thomas的回答略微清晰,但您可以使用requestInjection
或requestStaticInjection
从模块中配置单身注射。
// In your Module:
requestInjection(Legacy.getInstance()); // for an instance field, or
requestStaticInjection(Legacy.class); // for a static field.
docs on the wiki警告有关缺点:
不建议将此API用于一般用途,因为它遇到许多与静态工厂相同的问题:测试时笨拙,依赖性不透明,依赖于全局状态。
答案 2 :(得分:1)
这是一个有些讨厌的解决方案。
在你的应用程序的引导中,
可能在方法$re = '~.*/(.*)/~';
$str = 'equest lorem ipsum dawhdk scripts. Problem: a href="__;_base_url_j;p_i;oj/index.php?/forums/topic/975-example-maps-to-local-rating/" then does something, ';
preg_match_all($re, $str, $matches);
// Print the entire match result
var_dump($matches);
中,
你应该已经有类似的代码:
public static void main(String[] args)
在这个地方添加以下行:
Injector injector = Guice.createInjector(yourModule);
通过这样做,injector.injectMembers(Legacy.getInstance());
单身中的所有@Inject
s
应该解决。
另请参阅Injector.injectMembers的javadoc。