java 使用 Guice 注入特定实例

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16748126/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 23:52:22  来源:igfitidea点击:

Injecting specific instance with Guice

javadependency-injectionguice

提问by halfwarp

I'm having a few problems injecting a specific field instance with Guice.

我在使用 Guice 注入特定字段实例时遇到了一些问题。

Here's what I currently have:

这是我目前拥有的:

class Driver {
   private ThreadLocal<Database> db;

   ...
}

I'd usually just pass the db instance in a constructor. But this class will be intercepted, using guice.

我通常只是在构造函数中传递 db 实例。但是这个类会被拦截,使用guice。

Here's the module:

这是模块:

 class MyGuiceModule extends AbstractModule {

    private ThreadLocal<Database> dbToInject;

    public MyGuiceModule(ThreadLocal<Database> dbToInject) {
         this.dbToInject = dbToInject;
    }

    @Override
    protected void configure() {

         // Binds the interceptor.
         bindInterceptor(....);

         bind(ThreadLocal.class).toInstance(this.dbToInject);
    }
 }

And here's how I'm instantiating all the stuff:

这是我实例化所有东西的方式:

Injector injector = new Injector(new MyGuiceModule(db));
Driver driver = injector.getInstance(Driver.class);

I bet it's pretty obvious, but what am I doing wrong here?

我敢打赌这很明显,但我在这里做错了什么?

EDIT:

编辑:

Sorry if I wasn't clear. My problem is that this is not working. The instance is not being injected. I've annotated the field with @Inject and still doesn't work.

对不起,如果我不清楚。我的问题是这不起作用。未注入该实例。我已经用@Inject 注释了该字段,但仍然不起作用。

回答by Mingyu

  1. I think you need to use Guice.createInjectorto create an injector instance.

    Here's how I would create an injector:

    Injector injector = Guice.createInjector(new MyGuiceModule(db));
    
  2. Another thing is you used the following code to perform binding:

    bind(ThreadLocal.class).toInstance(this.dbToInject);
    

    Usually, it would be something like:

    bind(MyInterface.class).toInstance(MyImplementation.class);
    

    Your ThreadLocal.class is not an interface class, and this.dbToInject is not your implementation class.

  1. 我认为您需要使用Guice.createInjector来创建一个注入器实例。

    下面是我将如何创建一个注入器:

    Injector injector = Guice.createInjector(new MyGuiceModule(db));
    
  2. 另一件事是您使用以下代码执行绑定:

    bind(ThreadLocal.class).toInstance(this.dbToInject);
    

    通常,它会是这样的:

    bind(MyInterface.class).toInstance(MyImplementation.class);
    

    您的 ThreadLocal.class 不是接口类,而 this.dbToInject 也不是您的实现类。

Here's the documentation:

这是文档:

http://code.google.com/p/google-guice/wiki/Motivation

http://code.google.com/p/google-guice/wiki/Motivation

Hope this helps.

希望这可以帮助。

回答by condit

It would probably be better not to inject the ThreadLocaldirectly but to inject the Database into the constructor (as @Tobias suggested). And do you really want to use the same Database for all the instance of the Driver that are created (note the optional singleton in the comment)?

最好不要ThreadLocal直接注入,而是将数据库注入构造函数(如@Tobias 建议的那样)。并且您真的想对创建的所有驱动程序实例使用相同的数据库(注意注释中的可选单例)?

public class GuiceExample {

  public static class MyGuiceModule extends AbstractModule {
    @Override
    protected void configure() {
      bind(Driver.class);
    }

    @Provides
    //Uncomment this to use the same Database for each Driver
    //@Singleton
    Database getDatabase() {
      return new Database();
    }
  }

  @Test
  public void testInjection() {
    Injector i = Guice.createInjector(new MyGuiceModule());
    i.getInstance(Driver.class);
  }

  public static class Database {}

  public static class Driver {
    ThreadLocal<Database> db = new ThreadLocal<Database>();

    @Inject
    Driver(Database db) {
      this.db.set(db);
    }
  }

}