Dependency injection 如何将默认Guice提供程序注入到我的自定义提供程序中?

Dependency injection 如何将默认Guice提供程序注入到我的自定义提供程序中?,dependency-injection,guice,Dependency Injection,Guice,如果我创建一个提供程序并将其绑定到一个类,如下所示 bind(MyClass.class).toProvider(MyClassProvider.class) 然后,Provider自动绑定到MyClassProvider。如果要将提供程序注入MyClassProvider,这是一个问题,如下所示: @Inject public MyClassProvider(Provider<MyClass> provider) @Inject 公共MyClassProvider(提供程序)

如果我创建一个提供程序并将其绑定到一个类,如下所示

bind(MyClass.class).toProvider(MyClassProvider.class)
然后,
Provider
自动绑定到MyClassProvider。如果要将
提供程序
注入
MyClassProvider
,这是一个问题,如下所示:

@Inject
public MyClassProvider(Provider<MyClass> provider)
@Inject
公共MyClassProvider(提供程序)
我想将默认的Guice提供程序注入到我的提供程序中,以便可以在自定义提供程序中轻松创建新实例。如何做到这一点?

您需要在其中一个上使用。如果你不介意MyClass的用户被注释的话,这很容易

public class AccountTest {

   @Test
   public void test() {
       Injector injector = Guice.createInjector(new AbstractModule() {

           @Override
           protected void configure() {
               bind(MyClass.class).annotatedWith(Names.named("MYPROVIDER")).toProvider(MyClassProvider.class);
           }
       });
       MyClassUser user = injector.getInstance(MyClassUser.class);

       assertTrue(user.get().myProvider); // Shows if was created via my provider or the Guice provider.
   }
}

class MyClassUser {
    Provider<MyClass> provider;

    @com.google.inject.Inject
    public MyClassUser(@Named("MYPROVIDER") Provider<MyClass> provider) {
        this.provider=  provider;
    }

    MyClass get() {
        return provider.get();
    }
}

class MyClass {
    boolean myProvider = false;
}

class MyClassProvider implements Provider<MyClass> {
    Provider<MyClass> provider;

    @com.google.inject.Inject
    public MyClassProvider(Provider<MyClass> provider) {
        this.provider=  provider;
    }

    @Override
    public MyClass get() {
        MyClass c = provider.get();
        c.myProvider = true;
        return c;
    }

    public String toString() {
        return "Our provider";
    }
}
公共类AccountTest{
@试验
公开无效测试(){
Injector=Guice.createInjector(新抽象模块(){
@凌驾
受保护的void configure(){
bind(MyClass.class).annotatedWith(Names.named(“MYPROVIDER”)).toProvider(MyClassProvider.class);
}
});
MyClassUser=injector.getInstance(MyClassUser.class);
assertTrue(user.get().myProvider);//显示是通过my provider还是Guice provider创建的。
}
}
类MyClassUser{
提供者;
@com.google.inject.inject
公共MyClassUser(@Named(“MYPROVIDER”)提供程序){
this.provider=provider;
}
MyClass get(){
返回provider.get();
}
}
类MyClass{
布尔值myProvider=false;
}
类MyClassProvider实现提供程序{
提供者;
@com.google.inject.inject
公共MyClassProvider(提供程序){
this.provider=provider;
}
@凌驾
公共MyClass get(){
MyClass c=provider.get();
c、 myProvider=true;
返回c;
}
公共字符串toString(){
返回“我们的提供商”;
}
}
如果您不希望MyClass的用户使用命名的提供程序,那么我能够让它工作的唯一方法就是扩展
MyClass
,并让
MyClassProvider
需要一个“
MyClass2
”提供程序。作为一个解决方案,它闻起来很臭,但起了作用(与其用一个糟糕的答案污染这个答案,不如在上面找到代码)


您可以使用专用模块或子模块(因为这是机器人腿问题的一个变体)执行此操作,但我无法解决如何执行此操作。

为什么要执行此操作?MyClassProvider将执行provider.get()而不是new MyClass()?我之所以要执行此操作,是因为MyClass的构造函数并不是那么简单——它有其他注入的依赖项,而这些依赖项又有依赖项。第二个原因是,实际上我正在编写一个泛型提供程序,我希望将其用于许多实际类,如:bind(MyClass.class).toProvider(newTypeLiteral(){});好的,第一个原因。这个通用提供者将做什么?可能还有其他解决方案。通用提供程序将请求的类路由到特定的缓存实例。(路由基于HTTP请求中的头,返回的实例特定于后端实例)我认为可以使用自定义Guice作用域以某种方式实现,但我认为这会更难实现。基本上,如果HTTP请求中指示的标记后端之前已创建,我返回以前构建的缓存实例。如果这是第一次,我将使用guice的默认提供程序创建整个对象图。当然,我的DB连接提供程序会根据HTTP请求再次检查要连接的后端。关键是我不必在每次请求时构建整个对象图,但前提是我第一次连接到某个后端。所以我想要的是一个“命名的单身汉”。(名称基于http请求)