【问题标题】:Giving a value to Provider in guice在 guice 中为 Provider 赋值
【发布时间】:2013-08-29 08:35:19
【问题描述】:

我有以下提供者:

class MyProvider implements Provider<T> {
  private final ClassX objectX;
  private String name;

  @Inject
  public MyProvider(ClassX objectX) {
    this.objectX = objectX
  }

  T get() {
    // uses name and objectX to provide an object of T
  }
}

我的绑定如下所示:

List<String> names;
for (String name : names) {
  bind(T.class).annotatedWith(Names.named(name))
    .toProvider(MyProvider.class)  // somehow set name in Provider
}

provider 的构造函数参数可以从其他模块获得(并且注入器是从这个和那个其他模块创建的)。我无法弄清楚如何将该名称提供给提供者。理想的方法是将它也作为构造函数参数,在绑定中设置它的值。知道如何实现这样的目标吗?

【问题讨论】:

    标签: java guice provider


    【解决方案1】:

    我终于做到了

    class MyProvider implements Provider<T> {
      private ClassX objectX;
      private final String name;
    
    
      public MyProvider(String name) {
        this.name = name;
      }
    
      @Inject
      public setClassX(ClassX objectX) {
        this.objectX = objectX
      }
    
      T get() {
        // uses name and objectX to provide an object of T
      }
    }
    

    还有绑定:

    List<String> names;
    for (String name : names) {
      MyProvider provider = new MyProvider(name);
      requestInjection(provider);
      bind(T.class).annotatedWith(Names.named(name))
        .toProvider(provider)  // somehow set name in Provider
    }
    

    requestInjection() 方法是关键,它基本上将对象从同一个注入器中注入到带有 @Inject 注释的方法中。

    【讨论】:

      【解决方案2】:

      我认为你做不到。 Guice 绑定应该始终是特定的;每个绑定键标识 Guice 在某个注入点必须注入的内容,由一个类型和一个可能的注释组成:(Type, Optional&lt;Annotation&gt;) -&gt; Implementation,您不能在此处省略类型,这是您真正想要实现的目标。

      但是,Guice 能够绑定通配符类型,即可以将List&lt;?&gt; 绑定到某个提供程序(使用TypeLiteral)。所以,我想,你应该能够创建一个类,比如Cell&lt;T&gt;,它包装了一个T 类型的对象,并为Cell&lt;?&gt; 创建一个绑定。但是,您应该只能注入 Cell&lt;?&gt;,而不是像 Cell&lt;String&gt; 这样的具体类型。我不确定,也许 Guice 允许这种魔法,但可能性不大。

      顺便说一句,您可以将任何参数传递给提供者构造函数,并通过字段或方法提供其托管依赖项。然后您可以绑定到该提供程序的实例:

      bind(Smth.class).toProvider(new SmthProvider("whatever"));
      

      【讨论】:

      • 如果托管依赖项由字段或方法提供,则在执行 new SmthProvider("whatever"); 时不会注入这些对象;
      • 嗯,我认为它会工作。好吧,不可能什么都知道:)
      • @Aman 实际上,toProvider() 自动对其参数执行成员(字段和设置器)注入。
      【解决方案3】:

      您可以在提供程序中动态查找对象。但是,您必须提前知道您可能想要的所有名称。这将起作用:

      class MyProvider implements Provider<T> {
        private final Class<T> objectX;
        private final String name;
      
        @Inject
        public MyProvider(Class<T> objectX, String name) {
          this.objectX = objectX
          this.name = name;
        }
      
        public T get() {
          // uses name and objectX to provide an object of T
        }
      

      }

      然后是绑定 - 每个名称都需要一个提供程序实例:

      List<String> names = ...;
      for (String name : names) {
        bind(SpecificType.class).annotatedWith(Names.named(name))
          .toProvider(new MyProvider<SpecificType>(SpecificType.class, name));
      }
      

      如果您正在缓存结果或类似的东西,您可能需要一些同步。

      【讨论】:

        猜你喜欢
        • 2015-05-01
        • 2016-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-07
        • 1970-01-01
        • 2019-05-24
        相关资源
        最近更新 更多