我试图重构一些依赖单例对象的代码,我发现这些代码在Java中是有问题的。我的目标是创建我的AES密码类的线程安全实例,我可以在整个应用程序中访问它。
在关于Guice的几个教程之后,我有了这个非常基本的场景:
@Singleton
public class AESCipherService { // service class
@Inject
AESCipherService() {}
public void makeKeys() {
Log.d(Constants.TAG, "aes cipher generating keys");
}
}
这让我感到困惑,因为我的服务类没有子类,但我看到的所有示例都是关于将服务超类绑定到其子类之一。
public class AppInjectorModule extends AbstractModule {
@Override
protected void configure() {
bind(AESCipherService.class);
}
}
public class MyApplication {
private AESCipherService cipher;
@Inject
public void setCipher(AESCipherService cipher) {
this.cipher = cipher;
}
public void makeKeys() {
cipher.makeKeys();
}
}
最后,活动onCreate
所有应该从以下地方启动:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
Log.d(Constants.TAG, "dependency injection test starting");
Injector injector = Guice.createInjector(new AppInjectorModule());
// EDIT: added this line, but it never prints!
Log.d(Constants.TAG, "injector instantiated");
// instantiates the singleton object ???
MyApplication app = injector.getInstance(MyApplication.class);
app.makeKeys();
}
不幸的是,我得到的唯一输出是dependency injection test starting
。我没有看到aes cipher generating keys
,正如我所希望的那样。
依赖注入错误在哪里?
编辑:我添加了一些打印语句,以查看失败的原因。它似乎永远不会从实例化注入器对象返回。知道为什么会失败吗?它清楚地解释了为什么我的服务类没有运行。
答案 0 :(得分:1)
您没有惯用Guice。使用Guice的正确方法是在启动时创建注入器一次,使用它来创建初始类(在本例中为Activities),并让注入框架在链中创建所有注入。 / p>
创建注入器是一项昂贵,慢速操作,因此您不想在单击按钮时调用它;它应该在应用程序启动时发生,因此用户不会注意到它。
由于您正在为Android开发,请考虑使用Roboguice以正确使用Guice。请参阅:Using Guice to inject dependencies into an Android activity's constructor
在此期间,尝试在您的活动的构造函数中调用Guice.createInjector
,将其另存为实例字段,然后在getInstance
方法中调用onCreate
。
答案 1 :(得分:0)
您还需要绑定MyApplication.class
public class AppInjectorModule extends AbstractModule {
@Override
protected void configure() {
bind(AESCipherService.class).in(Singleton.class);
bind(MyApplication.class).in(Singleton.class);
}
}