在父Guice模块上使用requiresExplicitBindings导致"未明确绑定"已检查提供商

时间:2016-07-09 19:11:42

标签: java junit dependency-injection guava guice

我正在尝试使用Guice检查的提供程序来创建一个特别昂贵的对象。想法是懒洋洋地加载它,这样创建就不会影响应用程序启动时间,并且如果无法创建异常则处理异常。我跟着Guice wiki并将提供程序绑定在自己的特定模块中。我还绑定了另一个类,它将提供程序作为依赖项注入同一个模块。然后将该模块安装在另一个根模块中,我就能够从中成功创建注入器。当我尝试将binder().requiresExplicitBindings()添加到根模块以防止Guice仅在时间绑定中创建时,会出现此问题。错误是:

Explicit bindings are required and <class> is not explicitly bound.

当我删除binder().requiresExplicitBindings()时,会成功创建将提供程序注入依赖项的类。我假设Guice不为提供者创建JIT绑定(?)。

所以问题是,我可以使用已检查的提供程序并使模块同时需要显式绑定吗?这是Guice的限制还是我错误地实现了它?下面给出了一个可以使用JUnit运行并再现问题的示例。

Java版本:1.8

Guice版本:4.1.0

import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;

import org.junit.Test;

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Scopes;
import com.google.inject.throwingproviders.CheckedProvider;
import com.google.inject.throwingproviders.ThrowingProviderBinder;

class MyException extends Exception {
    public MyException() {
        super();
    }
}

interface MyProvider<T> extends CheckedProvider<T> {
    @Override
    public T get() throws MyException;
}

class MyStringProvider implements MyProvider<String> {
    @Override
    public String get() throws MyException {
        return "myString";
    }
}

class MyStringUser {
    @Inject
    public MyStringUser(final MyProvider< String > myStringProvider) {}
}

class MyModule extends AbstractModule {
    @Override
    protected void configure() {
        ThrowingProviderBinder.create(binder())
            .bind(MyProvider.class, String.class).to(MyStringProvider.class)
            .in(Scopes.SINGLETON);

        bind( MyStringUser.class );
    }
}

class MyMainModule extends AbstractModule {
    @Override
    protected void configure() {
        binder().requireExplicitBindings();

        install( new MyModule() );
    }
}

public class GuiceTest {
    @Test
    public void test_givenMyMainModule_whenCreatingInjector_thenReturnNonNullValue() throws Exception {
        assertThat( Guice.createInjector( new MyMainModule() ), is( notNullValue() ) );
    }
}

0 个答案:

没有答案