Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.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 如何使用两个安装公共依赖项模块的GUI模块_Java_Guice - Fatal编程技术网

Java 如何使用两个安装公共依赖项模块的GUI模块

Java 如何使用两个安装公共依赖项模块的GUI模块,java,guice,Java,Guice,我正在从事一个由四部分组成的项目: 将所有内容整合在一起的主项目。它包含publicstaticvoidmain(String…args)入口点 组件A 组件B A和B都参考的第三方通用组件 我使用Guice来处理所有四个部分之间的管道,这就是我的问题: 在As和Bs主GUI模块中,我安装了一个模块,该模块扩展了Common中定义的模块。在运行时,此安装程序失败,并出现以下错误: 已在common.AbstractCommonModule.configure()上配置了到common.Som

我正在从事一个由四部分组成的项目:

  • 将所有内容整合在一起的
    主项目。它包含
    publicstaticvoidmain(String…args)
    入口点
  • 组件
    A
  • 组件
    B
  • A
    B
    都参考的第三方
    通用
    组件
我使用Guice来处理所有四个部分之间的管道,这就是我的问题:
A
s和
B
s主GUI模块中,我安装了一个模块,该模块扩展了
Common
中定义的模块。在运行时,此安装程序失败,并出现以下错误:

已在
common.AbstractCommonModule.configure()
上配置了到
common.SomeClass
的绑定。[]

原因是我调用了
common.AbstractCommonModule.configure()
两次;一次是从组件
a
com.a.MainModule.configure()
安装
common.AbstractCommonPrivateModule
的子类实例,第二次是从组件
B
com.B.MainModule.configure()
安装

Main
中只安装
common.AbstractCommonPrivateModule
的一个实例不是一个选项,因为
AbstractCommonPrivateModule
实现了一个特定的绑定方法
BindComplexDuff(ComplexDuff)
,我只知道
a
B
中的参数,分别

我试图通过将
A
B
各自的主Guice模块包装在s中来解决这个问题。但是,此操作失败,出现下一个错误:

无法为%s创建绑定。它已在一个或多个子注入器或专用模块上配置%s%n如果它在专用模块中,是否忘记公开绑定?[]

在我的例子中,
A
B
各自的主Guice模块实际上是s-显然我可以从
main
安装两次

如何绕过这些错误并安装两次
AbstractCommonPrivateModule
模块?


编辑:我上传了一些示例代码(并解释了一些细节)

而不是让
A
B
安装
Common
,让他们
requireBinding()
为他们需要的类从
Common
下载。然后依赖于
A
B
的模块也需要安装
Common
。这可能有点奇怪,但实际上是可取的,因为
a
B
现在与
Common
的耦合不那么紧密


更新

我之所以要安装两个Shiro模块,是因为我希望只使用一个Shiro配置(一个不支持密码保护资源的配置)来保护
ui
模块中的Jersey资源,而
api
模块中的所有Jersey资源应使用完全不同的Shiro配置(仅将承载令牌理解为身份验证机制)进行保护

从广义上讲,这是难以解决的。Guice
Injector
为整个应用程序提供了一种做事的方式(通常是一个接口的一个实现);每个包没有不同的机制。您的两个
Module
SwsApiServletModule
SwsUiServletModule
提供了许多相同的绑定,并且
SwsModule
将它们一起安装。本质上,您说的是“Guice,请提供基于承载令牌的身份验证机制”,然后紧接着说“Guice,请提供基于密码的身份验证机制”。它只能做一个或另一个,因此它不会随意选择一个,而是失败得很快

当然,有很多解决方案,具体取决于您的需求。最常见的是使用和让UI和API代码请求不同的注释。这样,您就可以为同一接口或类安装两个不同的实现(具有不同的注释)

下面是一个例子:

package api;

public class ApiResources {
  @Inject
  public ApiResources(@ApiAuthMechanism AuthMechanism auth) {
    this.auth = auth;
  }
}

---

package api;

public class ApiModule implements Module {
  public void configure() {
    bind(AuthMechanism.class).annotatedWith(ApiAuthMechanism.class)
        .to(BearerTokenAuthMechanism.class);
  }
}

---

package ui;

public class UiResources {
  @Inject
  public UiResources(@UiAuthMechanism AuthMechanism auth) {
    this.auth = auth;
  }
}

---

package ui;

public class UiModule implements Module {
  public void configure() {
    bind(AuthMechanism.class).annotatedWith(UiAuthMechanism.class)
        .to(PasswordAuthMechanism.class);
  }
}

---

package webap;

public class WebappModule implements Module {
  public void configure() {
    // These modules can be installed together,
    // because they don't install overlapping bindings 
    install(new ApiModule());
    install(new UiModule());
  }
}
您在评论中提到,您无法控制正在安装的重叠绑定,因为它们来自第三方模块。如果是这样的话(我没有看到你的代码中发生了什么),出于安全原因,第三方可能不希望你做你想做的事情。例如 简单地绑定基于密码的机制可能会在整个应用程序中引入漏洞。也许值得尝试更好地理解第三方打算如何使用他们的模块

另一个不理想但适用于某些用例的选项是使用两个完全独立的
Injector
实例,每个实例具有一个绑定。然后手动将需要的实例直接传递给UI和API代码。这有点违背了Guice的目的,但并不总是错误的决定。使用可以减少痛苦



另外,您的“示例代码”非常庞大,可能超过90%与问题无关。将来,请花时间创建一个只包含与当前问题相关的代码的。任何人都无法通过筛选100多个Java文件和7300多行代码来理解您的问题。这不仅会使试图帮助您的人更容易,而且只要尝试创建一个演示问题的SSCCE通常就足以帮助您自己理解和解决问题。

要安装两次相同的模块,重写模块中的
.equals
方法以引用类而不是对象相等。Guice不会安装与已安装模块相同的模块。这并不重要
install new AbstractCommonPrivateModule();
@Override
public boolean equals(Object obj) {
    return obj != null && this.getClass().equals(obj.getClass());
}

// Override hashCode as well.
@Override
public int hashCode() {
    return this.getClass().hashCode();
}