为什么我的注入依赖项的方法没有运行?

时间:2015-08-24 16:52:19

标签: java android dependency-injection guice

我试图重构一些依赖单例对象的代码,我发现这些代码在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,正如我所希望的那样。

依赖注入错误在哪里?

编辑:我添加了一些打印语句,以查看失败的原因。它似乎永远不会从实例化注入器对象返回。知道为什么会失败吗?它清楚地解释了为什么我的服务类没有运行。

2 个答案:

答案 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);
    }
}