- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在做一个由四个部分组成的项目:
Main
项目。这包含 public static void main(String... args)
入口点。A
B
A
和 B
都引用的第 3 方 Common
组件。我正在使用 Guice 作为所有四个部分之间的管道,这是我的问题:
在 A
和 B
的主要 Guice 模块中,我安装了一个扩展了 Common
中定义的模块。在运行时,此设置失败并出现以下错误:
A binding to
common.SomeClass
was already configured atcommon.AbstractCommonModule.configure()
. [source]
原因是我调用了 common.AbstractCommonModule.configure()
两次;一次通过从组件 A
的 com.a.MainModule.configure()
安装 common.AbstractCommonPrivateModule
的子类实例,第二次来自组件 B
的 com.b.MainModule.configure()
。
在 Main
中仅安装 一个 common.AbstractCommonPrivateModule
实例不是一种选择,因为 AbstractCommonPrivateModule
实现了一个具体的 binder 方法 bindComplicatedStuff(ComplicatedStuff)
,我只知道 A
和 B
内部的参数。
我尝试通过将 A
和 B
各自的主要 Guice 模块包装在 PrivateModule
中来解决整个问题。 s。但是,这失败了,出现下一个错误:
Unable to create binding for %s. It was already configured on one or more child injectors or private modules %s%n If it was in a PrivateModule, did you forget to expose the binding? [source]
在我的例子中,A
和 B
各自的主要 Guice 模块实际上是 ServletModule
s - 显然我 可以 从 Main
安装两次。
我怎样才能绕过这些错误并安装 AbstractCommonPrivateModule
模块两次?
编辑:我上传了一些示例代码(带有一些细节的解释)to GitHub
最佳答案
不要让 A
和 B
安装 Common
,而是让它们 requireBinding()
用于类他们需要来自Common
。那么依赖A
或B
的模块也需要安装Common
。这可能感觉有点奇怪,但实际上是可取的,因为 A
和 B
现在与 Common
的耦合不那么紧密了。
更新
The reason I am installing two
ShiroWebModule
s is because I want the Jersey resources in theui
module to only be secured using one Shiro configuration (one that unserstands password-protecting resources), while all Jersey resources in theapi
module should be be secured using an entirely different Shiro configuration (one that understands only bearer tokens as an authentication mechanism).
从广义上讲,这是棘手的。 Guice Injector
为整个应用程序提供了一种做某事的方式(通常是接口(interface)的一种实现);每个包没有不同的机制。您的两个 Module
,SwsApiServletModule
和 SwsUiServletModule
提供了许多相同的绑定(bind),而 SwsModule
将它们安装在一起。本质上,您是在说“Guice,请提供基于承载 token 的身份验证机制”,然后紧接着说“Guice,请提供基于密码的身份验证机制”。它只能做一个或另一个,所以它不会随意选择一个,而是快速失败。
当然,有多种解决方案,具体取决于您的具体需求。最常见的是使用binding annotations并让 UI 和 API 代码请求不同的注释。这样你就可以安装同一个接口(interface)或类的两个不同的实现(带有不同的注解)。
这是一个例子:
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());
}
}
您在评论中提到您无法控制正在安装的重叠绑定(bind),因为它们来自第三方模块。如果是这种情况(我没有看到您的代码中发生了这种情况),出于安全原因,第三方可能不希望您做您想做的事情。例如,简单地绑定(bind)基于密码的机制可能会在整个应用程序中引入漏洞。可能值得尝试更好地了解第三方打算如何使用他们的模块。
另一种不理想但适用于某些用例的选项是使用两个完全独立的 Injector
实例,每个绑定(bind)一个。然后你手动将你需要的实例直接传递给 UI 和 API 代码。这在某种程度上违背了 Guice 的目的,但这并不总是错误的决定。使用 child Injector
s可以减轻这种痛苦。
顺便说一句,您的“示例代码”非常庞大,可能超过 90% 与问题无关。以后请花时间创建 SSCCE仅包含与手头问题相关的代码。根本没有任何人会筛选 100 多个 Java 文件和 7,300 多行代码来理解您的问题。这不仅会使试图帮助您的人更容易,而且只需尝试创建一个展示问题的 SSCCE 通常就足以帮助您自己理解和解决问题。
关于java - 如何使用安装公共(public)依赖模块的两个 Guice 模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33857582/
我听说最好不要从您系统的 Perl 版本所在的 CPAN 安装模块。我知道如何使用命令行安装模块,我只是想知道是否有办法将 CPAN 与系统核心 Perl 分开。 我应该: 下载源代码并专门为这些模块
我听说最好不要从系统的 Perl 版本所在的 CPAN 安装模块。我知道如何使用命令行安装模块,我只是想知道是否有办法将 CPAN 与系统的核心 Perl 分开。 我应该: 下载源代码并专门为这些模块
单独安装 electron 与通过 electron-builder 安装有什么区别?我正在使用 React 构建一个 Electron 应用程序,并且已经找到了一些教程。它们安装 Electron
两者安装有什么区别?我按照安装页面上的说明在全局范围内安装了 webpack,然后我转到了入门指南,据说在那里可以在本地安装 webpack-cli。 CLI = Command Line Inter
我在 OS X Yosemite 上用 PHP 安装了默认的 Apache 服务器,安装了 pear,用 brew 安装了 Solr (brew install solr),现在我正在尝试使用 PEC
我解压并编译了 Ruby 2.1 并安装了几个支持工具。 但是当我安装了 libssl-dev 时,OpenSSL 不会安装。 我在支持 openssl 时遇到这个错误: make: *** No r
我在 android studio 2.3.1 和 gradle 3.2 中设计了 2 到 3 个应用程序。当我从它运行应用程序到任何设备或模拟器时,一切都工作正常。但是当我从构建文件夹中获取该 ap
我注意到我正在读一本书提到通过 apt-get 安装 numpy 和 opencv apt-get install python-numpy python-opencv 但我可以通过以下方式在 pip
我正在尝试在 Windows 8.1 上安装 ansicon。我提取了文件并达到了我需要调用 ansicon -i 的级别。当我在 cmd 中输入此内容并运行 python 脚本时效果很好,但是当我通
我有 linux MINT 17.3 Kernel 4.4.0-81 所有更新可用。 (由于不同的原因,我无法迁移到更新版本的 ubuntu/mint) 我已经通过 PPA 安装了 FFMPEG(不是
尝试在本地运行我的应用程序时出现错误: 我只在 chrome 浏览器中收到此错误。我尝试过不同的东西,但我不确定为什么它是 Chrome 特定的。 最佳答案 我怀疑这不是 Firebase 问题,而是
这是我第一次开发 AngularJS 应用程序并使用脚手架工具 Yeoman ( http://yeoman.io/ )。我想对我的一些图标使用 fontawesome ( http://fortaw
我知道您通常“应该”$ pip install 如果包没有 brew ,但如果有一个你想安装的 python 包,你可以使用 $ pip install或 $ brew install为了?例如,通过
我正在尝试通过 RVM 安装 Ruby 1.9.3。然而,当谈到安装 RubyGems 时,我得到了这个: curl: (22) The requested URL returned error: 4
我是真正提出问题的新手,但你去吧。 我一直在尝试按照安装指南添加 dnsname: https://github.com/containers/dnsname https://github.com/c
Studio更新至0.4.0 建筑产量为“需要1.8版Gradle”;将设置设置为1.8 bin目录; 建立 “要求1.9级”;将设置设置为1.9 bin; 建立 “要求1.8级” 啊。不知道该怎么做
我刚刚注意到 kernel.org 因维护而停机。是否有使用不同镜子的不同公式?或者我可以向 Homebrew 软件添加不同的来源(如 bundler ?)? 谢谢你的帮助! 最佳答案 快速解决方法:
当我运行时: peardev install phpunit/PHPUnit 我得到以下信息: No releases available for package "pear.phpunit.de/P
服务器操作系统为Fedora 24. 64bit。 我想安装 Git 2.6.6。 所以下载源码并安装。 此服务器离线。所以我不使用“yum”。 ./configure --prefix=/usr/l
我正在尝试在我自己的服务器(操作系统:Linux Ubuntu Server 12.04)上安装 OpenEdX,但我遇到了同样的错误。谁能帮帮我? TASK: [ insights | insta
我是一名优秀的程序员,十分优秀!