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
相关产品推荐
相关产品推荐

