Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在Guice中管理复杂的生命周期_Java_Dependency Injection_Guice_Assisted Inject - Fatal编程技术网

Java 在Guice中管理复杂的生命周期

Java 在Guice中管理复杂的生命周期,java,dependency-injection,guice,assisted-inject,Java,Dependency Injection,Guice,Assisted Inject,我遇到了这样一种情况:我有一个数据对象图,并且希望为该图上的每个节点创建一个服务。问题在于,此服务(及其依赖项)依赖于它们工作的节点。大概是这样的: class Visitor { void enter(Node node){ Service service = guice.create(node) service.doComplexDomainLogic(/*some runtime information about the graph and the path to

我遇到了这样一种情况:我有一个数据对象图,并且希望为该图上的每个节点创建一个服务。问题在于,此服务(及其依赖项)依赖于它们工作的节点。大概是这样的:

class Visitor {

  void enter(Node node){
    Service service = guice.create(node)

    service.doComplexDomainLogic(/*some runtime information about the graph and the path to get here, other things*/)
  }
}
请注意,我在这里的目的是为图上的每个节点创建一个新的
服务
实例,以及一个新的
服务
依赖项实例

现在我有两个选择:

  • guice
    由辅助注射工厂提供支持。这就是我们目前正在做的,并且要求通过服务所依赖的一切来实现对节点的依赖,如果它们也依赖于
    节点
    。换句话说,如果我在这里使用辅助注入工厂,我必须对
    服务
    所依赖的每个类使用它,这是令人讨厌的
  • 我可以使用我们称之为嵌套引导程序的东西,也就是说,一个带有新注入器的新模块,实际上是一个新环境,在该环境的设置中,我可以编写
    bind(Node.class).toInstance(Node)
    。此代码将在第一次访问时执行,并缓存其结果
  • 我可以使用guice的自定义范围(我想)
我们在几个地方做了第二个,只是因为我和我的团队不知道自定义范围。我们现在还有一个自定义作用域的用途,我必须承认它的实现比我想要的要复杂得多。下面的内容很有帮助,但很明显,我将不得不深入到破旧的安全地带,而我最后一次去那里并不是很愉快


我应该使用什么guice工具来获得这种行为?

您可以注射
注入器
和您想要的零件。子注入器将允许您修改对象图并访问父注入器的所有依赖项,但您可以访问您的节点,访问深度随您的喜好而定

class Visitor {
  @Inject Injector injector;

  void enter(final Node node) {
    Service service = injector.createChildInjector(new AbstractModule() {
      @Override public void configure() {
        bind(Node.class).toInstance(node);
        // Anything that does require a Node should be bound here, because
        // you can't define it in the parent due to the unsatisfied binding.
        bind(SomeInterface.class).to(SomeClassThatRequiresNode.class);
      }
    }).getInstance(Service.class);

    service.doComplexDomainLogic(/* ... */)
  }
}
虽然可以对作用域执行类似的操作,但请记住,作用域仅用于标识。这意味着您可以创建一个
@NodeScoped
作用域,并确保在处理给定节点时返回相同的对象,但您仍然需要绑定某种
@NodeScoped NodeHolder
以在深入时保留节点。子注入器将允许您直接请求一个节点,这可能会使您的代码更易于理解和测试,而不是保留和填充这个单独的保持器

另见:

您不能为此使用提供商行为/工厂行为吗?不是注入注入器,而是注入一个具有所有必要依赖项的工厂,并使用它来获得正确的服务实例?因此,这就是我们目前正在做的,它有一个令人讨厌的副作用,即如果
服务
依赖于
组件
,而
组件
依赖于
节点
,然后我还需要为
组件
创建一个辅助注入工厂。如果
组件
依赖于
实用程序
,并且。。。等等这就是我所说的“向上”依赖的意思。哦,对不起,我误解了你的问题