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

如何在Guice中创建需要注入实例的动态绑定?

丁书
2023-03-14

我想创建一个动态绑定实例到命名注释的模块。用例是我想自动绑定配置中的值,属性文件中的键是@命名值。

然而,配置绑定在不同的模块中,所以我需要注入配置。我看过的解决方案是:

>

  • 绑定在confiure()方法中。这个方法没有注入,我不能得到基本配置。

    使用提供程序/@提供程序。提供程序只绑定一个实例。

    使用多活页夹。我的用例与这个扩展提供的有点不同。多重绑定允许您单独绑定多个实例,然后将它们作为包含更复杂类型的集合进行注入。我想分别绑定每个实例,并通过为后者唯一标识它们。

    使用儿童注射器。不幸的是,如果不对现有代码进行大量修改,这是不可能的。这个答案很好地描述了如何用这种方式解决这个问题。

    以某种方式注入粘合剂。(我开始变得有点刻薄了)Guice允许为后一种用途注入注入器,我尝试通过@Provides方法将活页夹注入模块,然后直接使用活页夹在方法中进行多个绑定。Guice不会注射粘合剂。

  • 共有1个答案

    屈健柏
    2023-03-14

    记住,所有的configure方法都会在任何注入发生之前配置Injector中的所有绑定。也就是说,有几件事:

    >

  • @Named属性绑定到单个属性实例的内容非常有用,因此有一个名称。bindProperties(…) 自动为您执行此操作的方法。唯一的诀窍是,在运行configure()时,需要有Properties实例。

    如果它们都同时可用,就不用担心在一个模块中绑定属性,在另一个模块中绑定应用程序。只要它们都进入同一个注入器,Guice就会将它们结合起来,让它们满足彼此的依赖性。

    提供者可以返回不同的实例,而且通常会返回——但这并不能帮助您区分密钥。如果直接注入属性实例太难看了,请考虑制造一个轻量级工厂来代替:

    public class ConfigOracle {
      @Inject private Properties properties;
    
      public String getAsString(String key) { ... }
      public int getAsInt(String key) { ... }
    }
    
    public class SomeConfigUser {
      @Inject private ConfigOracle configOracle;
    
      public void doStuff() {
        doStuffBasedOn(configOracle.getAsString("my.properties.key"));
      }
    }
    

    您永远不需要将活页夹(或其他任何东西)插入模块。

    • 如果您实现了Modulebinder将是confiure()的参数。如果您扩展了AbstractModule,只需调用binder()方法。
    • 如果需要,您可以通过构造函数参数将依赖项传递给模块,这(就我而言)是模块应该改变他们创建的绑定的唯一方法。
    • 没有理由你不能通过一个注射器来创建一个模块,但是你必须先有一个注射器,听起来你想摆脱只有一个注射器的困境。
    • 如果您需要来自Injector的其他实例,您可以始终使用@Inject字段/方法/构造函数编写提供程序实现,或者甚至在@提供程序方法中引入参数(将自动填充依赖项)。

    总的来说,我仍然喜欢子注入器方法(感谢链接和对我之前回答的赞美!),它最适合您的“基于注入实例的动态绑定”描述,实际上是这样简单的:

    class PropertiesModule extends AbstractModule {
      Properties properties;
    
      PropertiesModule(Properties properties) {
        this.properties = properties;
      }
    
      @Override public void configure() {
        Names.bindProperties(binder(), properties);
      }
    }
    
    Injector oldInjector = Guice.createInjector(allYourOtherModules);
    Module myModule = new PropertiesModule(oldInjector.get(Properties.class));
    Injector injector = oldInjector.createChildInjector(myModule);
    

  •  类似资料:
    • 假设有一个类A,它的构造函数是这样的: 还有AFactory: 所以要创建一个A的实例,我显然需要做这样的事情: 但是,假设我有其他类:例如,B类、C类和D类具有类型为A的成员(带有字段注入,但也可以是ctor): 我希望将 A 的相同实例注入到这些类中。但仍然可以选择将 A 的另一个实例注入其他类(假设 E 类和 F 类)。 正确的做法是什么?我就是想不出一个干净的方法来做到这一点。

    • 我们的项目设置如下: 1)主模块:包含一个启动Spark流服务器的驱动程序。它有自己的Guice注入器。 2)当消息进来时,它进入另一个模块,该模块创建它自己的Guice注入器。 3) 此模块使用其他模块中的类,这些模块本身使用依赖模块。这些模块中的每一个都创建了自己的Guice注入器,因此可以独立工作、单独测试等。 这里有一个问题:现在我们需要一个单例,但是作为@Singleton创建的对象绑定

    • 我很困惑绑定如何与Guice一起工作。我是一家公司的初级开发人员,我正在查看我们的代码库,试图了解我们是如何在应用程序中实现Guice的。 我正在阅读关于Guice注入的指南:https://www.tutorialspoint.com/guice/guice_first_application.htm,这看起来和我们公司的做法不一样。 第一步说创建接口。我们确实在模块类中有一个扩展的绑定。 例:

    • 问题内容: 我有类名称的列表,想动态创建它们的实例。例如: 如何在Python中动态创建该实例?谢谢! 问题答案: 这通常被称为反思或自省。找出类似的问题,这些问题可以回答您要尝试做的事情: Python是否具有与Java类forname等效的名称 您可以使用字符串实例化Python中的类吗

    • 我上了如下的课,效果很好 现在,我没有直接使用EmpService,而是创建了一个接口,EmpService实现了该接口,如下所示。 所以现在我的资源类必须使用接口,但我不确定如何引用它必须使用的实现。 我看到了这个,我不确定我的绑定应该去哪里。(这是我第一个与Guice相关的项目,所以我是一个完全的新手)。 这就是“未绑定com.api.EmpService的实现”出现的错误这完全可以理解,但不

    • 我使用Guice进行依赖注入,但在我的特定用例中,它给了我这个错误: