为什么我通过静态注入获得空指针异常?

时间:2015-05-19 16:42:51

标签: guice

JobDriver

public class JobDriver {
    @Inject
    static Provider<Manager> managerProvider;


    public static void main(final String[] args) {
        final JobDriver driver = new JobDriver();
        driver.execute();
    }

    private void execute() {
        final Manager manager = managerProvider.get();
        manager.execute();
    }
}

提供者类

public class ManagerProvider implements Provider<Manager> {

    public Manager get() {
       return new Manager();
    }
}

构造

public class Module extends AbstractModule {

    @Override
    protected void configure() {
        requestStaticInjection(JobDriver.class);
        bind(Manager.class).toProvider(ManagerProvider.class);
    }
}

注射器由弹簧启动,在createInjector方法中,它接收上面的模块。有一个更好的方法吗?我有两个进入系统的入口点。处理所有请求的一个通过spring,另一个是定期触发JobDriver类的计划作业。弹出容器在服务启动时启动,因此我假设在创建时所有注入的对象都可用。我在这里错过了什么?我希望整个系统能够共享这些单例对象。

1 个答案:

答案 0 :(得分:4)

requestStaticInjection documentation中所列,静态注入在创建注入器之前不会发生。看来JobDriver.main调用不会直接创建注入者,因此managerProvider会保留null

即使您没有抓住它也足以创建一个注射器:

public class JobDriver {
    @Inject
    static Provider<Manager> managerProvider;

    public static void main(final String[] args) {
        Guice.createInjector(new Module());
        final JobDriver driver = new JobDriver();
        driver.execute();
    }

    private void execute() {
        final Manager manager = managerProvider.get();
        manager.execute();
    }
}

...但是如果你想确保每个VM只创建一次Injector,你可能想要将它的创建提取到一个synchronized保护的注入器创建器方法,可能在它自己的类中。

(要求PSA:无论何时选择,都要避免静电注射,因为它可能会使事情变得难以理解和测试。)