当前位置: 首页 > 知识库问答 >
问题:

Guice中带有辅助注入的循环依赖关系

曾永新
2023-03-14

我在用Guice辅助注射。下面是一个标准场景:

Class TargetType {

   @Inject
   TargetType(@Assisted Param1 assistedParam, InjectedType injectedType) 
   {
      /* ... */
   }
}

Class InjectedType {

   @Inject
   injectedType(OtherInjectedType otherInjectedType) 
   {
      /* ... */
   }
}

现在,我可以使用Guice factory调用TargetTypeFactory.Create(assistedArg/*instanceof Param1*/),并通过Guice注入的InjectedType实例轻松获得我的TargetType实例。

我的问题是:如果我希望InjectedType引用正在创建的TargetType的实例,该怎么办?换句话说,我想要:

Class TargetType {

   @Inject
   TargetType(@Assisted Param1 assistedParam, InjectedType injectedType) 
   {

   }
}

Class InjectedType {

   @Inject
   injectedType(/* How to get this? -> */  TargetType constructedTargetType, OtherInjectedType otherInjectedType) 
   {

   }
}

我当前的解决办法相当难看:我手动创建了一个TargetType,而不使用InjectedType,然后使用InjectedType获取InjectedType实例,并在TargetType实例上调用SetInjectedType(InjectedType)方法。啊!

共有1个答案

澹台硕
2023-03-14

有趣的问题。我不认为有一个完全干净的解决方案,但也许这个基于儿童注射器的解决方案会适合你:

首先,创建一个自定义guice绑定注释供自己使用:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@BindingAnnotation
public @interface JamrozikParam {}

然后,将targettype更改为如下所示:

class TargetType {

   @Inject
   TargetType(@JamrozikParam Param1 assistedParam, InjectedType injectedType) 
   {

   }
}
Injector topInjector = Guice.createInjector(/* Your modules here */);
// Note that the modules used there can't mention TargetType or InjectedType
// Now many lines later
Param1 myP1val;
myP1val = // ... however that was computed
Injector childInjector = topInjector.childInjector(new Param1Module(myP1val));
TargetType t1 = childInjector.getInstance(TargetType.class);
public class Param1Module extends AbstractModule {
  private final Param1 p1val;
  public Param1Module(Param1 p1val) {this.p1val = p1val;}
  protected void configure() {
    bind(Param1.class).annotatedWith(JamrozikParam.class).toInstance(p1val);
    bind(TargetType.class).in(Singleton.class);
    bind(InjectedType.class).in(Singleton.class);
  }
}
class TargetType {

   @Inject
   TargetType(@Assisted Param1 assistedParam) 
   {

   }

   void ttMethod1(InjectedType injected, String other) { }
   // other methods
}

class InjectedType {

   @Inject
   injectedType(OtherInjectedType otherInjectedType) 
   {

   }

   void injMethod1(TargetType constructedTarget, String other) { }
   // other methods
}

class TargetTypeSupervisor {
  private TargetType target;
  private InjectedType injected;

  @Inject TargetTypeSupervisor(@Assisted Param1 assistedParam, InjectedType injected) {
    this.injected = injected;
    this.target = new Target(assistedParam);
  }

  void ttMethod1(String other) { target.ttMethod1(injected, other); }
  void injMethod1(String other) { injected.injMethod1(target, other); }
  // other methods as needed
}
 类似资料:
  • 我想引导一系列处理元素,并通过Guice将它们连接在一起。让我们假设以下路径: 需要一些输入 由实现需要 由实现需要 由实现需要 的依赖关系只能在运行时解决,而不能在配置时解决。通常的方法是在这种情况下使用辅助注入来创建工厂,该工厂将缺少的实例作为参数,如下所示: 但我真正想要的是这样的: 我不想在整个层次结构中手动传递AImpl的特定依赖项。使用Guice可以实现这一点吗?如果没有,在保持注射的

  • 我有一个工厂是这样的: 这样的类: 如何正确使用Google Guice来做同样的事情?我尝试了辅助注射,但我不确定如何创建“UrlBuilder”。谁能帮忙?

  • 我正在使用Guice Assisted Inject库为我建立一个工厂。我目前的设置如下: 这迫使我使用< code > factory . create controller(first,factory . create second(first))显式创建一个< code>SecondDep。是否可以更改我的绑定,这样我就可以简单地执行< code > factory . create con

  • 我喜欢在构造函数中传递运行时依赖项的主要原因是: 它使依赖关系成为必需的 它提供了设置实例变量的中心位置 将依赖项设置为实例变量,可以避免在类中从一个方法传递到另一个方法,或者将它分两次或多次传递给两个或更多个公共方法 这导致我在使用Guice时使用了很多辅助注射。与不使用DI相比,这会产生额外的代码,因此阅读以下内容:辅助注入到底有多有用? 似乎大多数人不会使用辅助注入在构造函数中传递运行时(派

  • 我一直在用guice做一个项目。 我有一个抽象类,它有很多实现。为了使用正确的实现,我使用一个工厂,它接收参数,然后返回正确的实例。 演示代码 我想知道的是,如果我可以用替换工厂,直接注入的实现(请注意,它们应该使用辅助注入)? 谢谢你。

  • 我已经使用google-guice和辅助注射机制有一段时间了。因为我在scala,刚刚发现scala-guice,我也对使用它感兴趣。但是我对如何使用辅助注射感到困惑。没有使用辅助注射的例子。 因此,我的问题是:是否可以使用scala guice辅助注射,如果可以,请提供一个简单的例子? 此外,对于google-guice,我使用以下库:javax.inject.jar、guice-3.0.jar