当前位置: 首页 > 面试题库 >

在Guice中管理同一依赖关系树的多个版本的最佳模式是什么?

鲁俊友
2023-03-14
问题内容

我想实例化同一种依赖关系树/链的多个版本,这些版本对树/链中的某些接口使用不同的实现。在这种情况下,最佳的Guice做法/模式是什么?

这是我的问题的一个具体例子。

我有一个Writer接口,它可能是文件编写器或标准输出编写器,它们位于我的依赖关系层次结构的叶子处。像这样:

interface Writer { ... }
class FileWriter implements Writer { ... }
class StdOutWriter implements Writer { ... }

另一个记录器接口用于在编写器上添加一个间接层。例如:

interface Logger { ... }

class LoggerImpl{
  @Inject
  public Logger(Writer out){ ... }
  public void log(String message){ out.println(message); }
}

然后有一个使用记录器的客户端。

class Client{
  @Inject
  public Client(Logger logger){ ... }
  public void do(){ logger.log("my message"); }
}

现在,我想在程序中使用两种类型的层次结构:

  1. 客户端-> LoggerImpl-> FileWriter
  2. 客户端-> LoggerImpl-> StdOutWriter

在没有为1和2使用单独的Guice模块的情况下,是否有一种很好的接线方法?

理想情况下,我希望有一个ClientFactory这样的课程:

interface ClientFactory{
  public Client stdOutClient();
  public Client fileClient(); 
  //or fileClient(File outputFile) for extra points ;)
}

谁能提出一种使用此工厂或其他方法进行连接的方法?

我还希望有一个解决方案,可以扩展到我有更多种类的较长依赖树/链的情况。谢谢!


问题答案:

这是机器人腿的问题。解决方案基本上是使用PrivateModule绑定每个依赖关系树,并仅公开该树的根。您可以通过多种方法来执行此操作,但是以下是您通常如何执行此操作的示例(可以根据需要对此进行很多更改):

public class ClientModule extends PrivateModule {
  private final Writer writer;
  private final Class<? extends Annotation> annotationType;

  public ClientModule(Writer writer, Class<? extends Annotation> annotationType) {
    this.writer = writer;
    this.annotationType = annotationType;
  }

  @Override protected void configure() {
    bind(Writer.class).toInstance(writer);
    bind(Logger.class).to(LoggerImpl.class);
    expose(Client.class).annotatedWith(annotationType);
  }
}

public class ClientFactoryModule extends AbstractModule {
  private final File file;

  public ClientFactoryModule(File file) {
    this.file = file;
  }

  @Override protected void configure() {
    install(new ClientModule(new StdOutWriter(), StdOut.class));
    install(new ClientModule(new FileWriter(file), FileOut.class));
    bind(ClientFactory.class).to(ClientFactoryImpl.class);
  }
}

public class ClientFactoryImpl implements ClientFactory {
  private final Client stdOutClient;
  private final Client fileClient;

  @Inject public ClientFactoryImpl(@StdOut Client stdOutClient, 
                                   @FileOut Client fileClient) {
    this.stdOutClient = stdOutClient;
    this.fileClient = fileClient;
  }

  ...
}

但是,您的方法方案Client fileClient(File)有很多不同。



 类似资料:
  • 保存package.json依赖项的最佳实践是什么? 例如,我看到很多依赖项是不固定的,比如:

  • 问题内容: 我有一个简单的节点应用程序,它对github上另一个应用程序具有单一依赖性。使用可以很好地安装依赖项,但是当我尝试在其中安装某些东西时,它说不可用。例如,github应用程序将Mongoose安装为依赖项。我认为该父应用程序可以访问该模块,因为它位于子模块中: 结构看起来像这样: 我是否只需要在父级应用程序中同时包含猫鼬作为依赖项,还是可以通过子级方式访问该模块? 问题答案: 我是否只

  • 假设<code>B:1.0.1,但是子项目应该依赖于<code>A:1.2(有意覆盖传递依赖性)。 很容易发现 ,并从它的所有子POM中删除样板文件。不幸的是,下面的设置导致在最终的工件中使用两个版本:< code>A:1.0.1(作为< code>B:1.0.1的依赖项)和< code>A:1.0.2(来自父pom中的显式声明)。 如何在所有子项目中强制使用< code>A:1.0.2版本,并在

  • 我正在使用Gradle的Spring Boot框架。我知道,为了包含一些Spring依赖项,我可以引用“starters”而不显式定义版本;该版本将由我选择的Spring Boot版本控制,它是Spring Boot Gradle插件的版本。示例(省略非相关的分级代码): 请注意,没有为我的应用程序依赖项定义显式版本。 我如何确保我为那些依赖项使用的版本与我的其他Spring Boot依赖项兼容?

  • Maven插件(maven-compiler-plugin: 3.8.1和maven-surefire-plugin: 3.0.0-M3)在运行mvn清洁包时似乎正在下载同一依赖项(plexus-utils)的多个版本,即使我在依赖项中指定了plexus-utils的最新版本。这不会导致任何错误,但3.0.16之前的任何版本的plexus-utils都容易受到命令注入的影响。有没有办法阻止这种情况

  • 粗略的讲, 依赖管理由两部分组成. 首先, Gradle 需要了解你的项目需要构建或运行的东西, 以便找到它们. 我们称这些传入的文件为项目的 dependencies(依赖项). 其次, Gradle 需要构建并上传你的项目产生的东西. 我们称这些传出的项目文件为 publications(发布项). 让我们来看看这两条的详细信息: 大多数项目都不是完全独立的. 它们需要其它项目进行编译或测试等