You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Guice中Provider存在但依赖实例为null的原因咨询

Google Guice依赖注入null问题排查

问题场景

刚接触Google Guice,编写了如下代码尝试理解其工作机制:

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provides;

public class GuiceTest {

    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new TestModule());
        TestClass testClass = injector.getInstance(TestClass.class);
        testClass.test();
    }

}

class TestClass {

    @Inject
    SomeClass someClass;

    public void test() {
        someClass.test();
    }

}

class SomeClass {

    @Inject
    SomeDependency someDependency;

    public void test() {
        someDependency.test();
    }

}

class SomeDependency {

    public void test() {
        System.out.println("SomeDependency test");
    }

}

class TestModule extends AbstractModule {

    @Override
    protected void configure() {}

    @Provides
    public SomeClass provideSomeClass() {
        return new SomeClass();
    }

    @Provides
    public SomeDependency provideSomeDependency() {
        return new SomeDependency();
    }

}

运行后发现SomeClass注入正常,但SomeClass中的SomeDependency为null,明明已经在Module中定义了Provider,却不清楚原因。

原因分析

问题出在provideSomeClass方法里:你通过new SomeClass()手动创建了SomeClass的实例,Guice不会对手动创建的对象执行成员注入操作。也就是说,这个手动new出来的SomeClass对象,它的@Inject标记的someDependency成员不会被Guice自动填充,所以保持为null。

解决方案

有两种规范的解决方式:

方式一:移除SomeClass的@Provides方法,让Guice自动管理实例

因为SomeClass有默认无参构造方法,Guice可以自动实例化它并完成成员注入,不需要手动写Provider。修改后的TestModule如下:

class TestModule extends AbstractModule {
    @Override
    protected void configure() {}

    // 移除provideSomeClass方法
    @Provides
    public SomeDependency provideSomeDependency() {
        return new SomeDependency();
    }
}

方式二:在@Provides方法中注入SomeDependency并传递给SomeClass

如果一定要保留provideSomeClass方法,需要让Guice把SomeDependency注入到Provider方法中,再传递给SomeClass(推荐用构造方法注入替代字段注入,更符合依赖注入规范)。

首先修改SomeClass,改用构造方法注入:

class SomeClass {
    private final SomeDependency someDependency;

    @Inject
    public SomeClass(SomeDependency someDependency) {
        this.someDependency = someDependency;
    }

    public void test() {
        someDependency.test();
    }
}

然后修改provideSomeClass方法,让Guice注入SomeDependency:

@Provides
public SomeClass provideSomeClass(SomeDependency someDependency) {
    return new SomeClass(someDependency);
}

这样Guice会自动把SomeDependency的实例传入Provider方法,创建的SomeClass实例就会拥有正确的依赖。

内容的提问来源于stack exchange,提问作者WitHeld

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 20:35:24