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

Guice和“作用域”单例

段恩
2023-03-14

我试图学习Guice,但下面的场景似乎很难。假设我有A、B和C类。我应该能够做到以下几点(注意,这个例子在某种程度上简化为实际情况):

  1. A是全球单身人士

当B创建C时,C的依赖项B必须是相同的实例,即从C的角度来看,B是单例的。

我尝试过创建儿童注射器:

private static class MainModule extends AbstractModule{

    @Override
    protected void configure() {
        bind(A.class).in(Singleton.class);
    }

    @Provides
    B createB(Injector injector){
        return injector.createChildInjector(new SubModule()).getInstance(B.class);
    }
}

private static class SubModule extends AbstractModule{

    @Override
    protected void configure() {
        bind(B.class).in(Singleton.class);
        bind(C.class);
    }
}

public static void main(String[] args) {
    Injector injector = Guice.createInjector(new MainModule());

    A a = injector.getInstance(A.class);

    B b1 = a.getB();
    B b2 = a.getB();

    // all following C's are different instances
    C b1c1 = b1.getC(); //this has b1 and a
    C b1c2 = b1.getC(); //this has b1 and a

    C b2c1 = b2.getC(); //this has b2 and a
    C b2c2 = b2.getC(); //this has b2 and a

}

但是Guice给出了B已经绑定的错误(MainModule中提供了方法)。因此,我需要覆盖MainModule的B绑定,但这似乎不可能使用子注入器。

该问题可以通过使用多个喷油器来解决,例如,为createB方法创建一个新喷油器,并将喷油器A作为参数,但使用多个喷油器似乎不是最佳做法。

编辑:向C实例添加注释,以澄清它们应该拥有哪个B实例

共有1个答案

苏高旻
2023-03-14

我将把它作为一个答案发布,它更像是一种变通方法,而不是完整的解决方案,但对我的应用程序来说可能已经足够好了:

private static class MainModule extends AbstractModule{

    @Override
    protected void configure() {
        bind(A.class).in(Singleton.class);
        bind(SubModule.class).in(Singleton.class);
    }

    @Provides
    B createB(Injector injector){
        SubModule m = injector.getInstance(SubModule.class);
        return Guice.createInjector(m).getInstance(B.class);
    }
}

private static class SubModule extends AbstractModule{

    private final A a;

    @Inject
    public SubModule(A a) {
        this.a = a;
    }

    @Override
    protected void configure() {
        bind(A.class).toInstance(a);
        bind(B.class).in(Singleton.class);
        bind(C.class);
    }
}

首先,我认为大多数绑定都在main模块中,但我想如果它们只在B的上下文中使用(并像我在A中那样路由其他绑定),那么它们无论如何都可以移动到子模块。这与链接问题的答案非常相似:依赖项注入:按区域(Guice、Spring等)确定范围,但我创建了新的顶级注入程序,因为我似乎无法在两个模块中绑定B,或者我可能会错过一些东西。。

(第一次这样做时,不确定这是否是正确的方法,将工作作为自己的答案)

 类似资料:
  • Atom支持语言特定的设置。你可以在Markdown文件中软换行,或者在Python中把tab的宽度设置为4。 语言特定的设置只是一些东西的子集,我们把它叫做“作用域设置”。作用域设置可以只作用于一类特定的语法符号。比如你可以仅仅对Ruby的注释,Markdown中的代码段,或者JavaScript函数名称进行设置。 语法符号中的作用域名称 编辑器的每个符号都有一系列的作用域名称。例如,前面提到的

  • 本文向大家介绍Javascript变量的作用域和作用域链详解,包括了Javascript变量的作用域和作用域链详解的使用技巧和注意事项,需要的朋友参考一下 工作这几年,js学的不是很好,正好周末有些闲时间,索性买本《js权威指南》,大名鼎鼎的犀牛书,好好的把js深入的看一看。买过这本书的第一印象就是贼厚,不过后面有一半部分都是参考手册。 一:作用域   说起变量第一个要说到的肯定就是作用域,正是因

  • 我有一个以下类别的StorageProxy。java(接口)StorageProxyImpl1。java(StorageProxy接口的实现1) 我在Application类中有一个main方法,用于初始化和使用Resource1和Resource2。 我想为StorageProxy提供依赖注入的指导,这样在创建新的实现时就不会有太大的麻烦。我希望Resource1和Resource2使用相同的S

  • 假设有两个类ClassA和ClassB。假设ClassB依赖于ClassA。在配置文件中,如果我们将ClassA的作用域定义为singleton,而将ClassB的作用域定义为Prototype,那么每次创建ClassA的bean实例时ClassB的实例会发生什么?每次返回ClassA实例时,会返回相同的ClassB实例还是创建新实例? 谢谢!!!

  • 前言 面试问题: 说一下对变量提升的理解 说明this的几种不同的使用场景 创建10个<a>标签,点击的时候弹出来对应的序号 如何理解作用域 实际开发中闭包的应用 涉及到的知识点: 执行上下文 this 作用域 作用域链 闭包 执行上下文 执行上下文主要有两种情况: 全局代码: 一段<script>标签里,有一个全局的执行上下文。所做的事情是:变量定义、函数声明 函数代码:每个函数里有一个上下文。

  • Spring框架中session和globalSession的区别是什么? 根据我的研究,这两者在Web感知的Spring ApplicationContext上下文中都是有效的。