如何对现有的单例类使用guice注入?

时间:2017-04-14 00:02:53

标签: java dependency-injection guice

我有一个名为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注入我的程序,但保持当前的老派单身范式,而不是对其他一切做太多改变?

修改 下面至少有三个解决方案,我不太清楚哪个是最好的,或者它们是否相同。

3 个答案:

答案 0 :(得分:3)

我刚刚找到另一个解决方案:

// put in the module
bind(Legacy.class).toInstance(Legacy.getInstance());

在此示例中,您的模块本身(而不是Guice)负责获取Legacy实例,然后要求Guice始终使用此单个实例来完成所有Legacy注入请求。 但根据javadoc 创建Injector时,它将自动为此实例执行字段和方法注入,但Legacy上的任何可注入构造函数都将被忽略。请注意,使用此方法会导致无法控制的“急切加载”行为。

答案 1 :(得分:2)

虽然只比Thomas的回答略微清晰,但您可以使用requestInjectionrequestStaticInjection从模块中配置单身注射。

// 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。