我正在开展一个由四部分组成的项目:
Main将所有事物融合在一起的项目.这包含public static void main(String... args)入口点.ABCommon组件,这两个A和B参考.我正在使用Guice来处理所有四个部分之间的管道,这就是我的问题:
在As和Bs主要的Guice模块中,我安装了一个扩展了一个模块的模块Common.在运行时,此设置失败,并显示以下错误:
common.SomeClass已配置绑定到common.AbstractCommonModule.configure().[ 来源 ]
原因是我要调用common.AbstractCommonModule.configure()两次; 一旦通过安装的子类实例common.AbstractCommonPrivateModule从组件A的com.a.MainModule.configure(),并从部件的第二时间B的com.b.MainModule.configure().
只安装一个common.AbstractCommonPrivateModule in 实例Main不是一个选项,因为AbstractCommonPrivateModule实现了一个特定的binder方法bindComplicatedStuff(ComplicatedStuff),我只分别知道其中的参数A和B.
我尝试通过将As和B各自的主要Guice模块包装在s中来解决这个问题PrivateModule.但是,由于下一个错误,此操作失败:
无法为%s创建绑定.它已经在一个或多个子注入器或私有模块上配置%s%n如果它在PrivateModule中,您是否忘记公开绑定?[ 来源 ]
在我的情况下,A's和B各自的主要Guice模块实际上是ServletModules - 显然我可以安装两次Main.
如何解决这些错误并安装AbstractCommonPrivateModule模块两次?
编辑:我向GitHub上传了一些示例代码(有关一些细节的说明)
dim*_*414 15
而不是拥有A和B安装Common,让他们requireBinding()的所需的类Common.然后依赖A或B将需要安装的模块Common.这可能会感到有点奇怪,但它实际上是可取的,因为A和B现在不太紧密耦合到Common.
更新
我安装两个
ShiroWebModules 的原因是因为我希望ui模块中的Jersey资源只能使用一个Shiro配置(一个解密密码保护资源)来保护,而api模块中的所有Jersey资源都应该使用完全不同的方式来保护Shiro配置(仅将承载令牌理解为认证机制的配置).
从广义上讲,这是棘手的.Guice Injector为整个应用程序提供了一种做某事的方法(通常是一个接口的实现); 每个包装没有不同的机制.你的两个Module,SwsApiServletModule并SwsUiServletModule提供了许多相同的绑定,并将SwsModule它们安装在一起.实质上你说"Guice,请提供基于bearer-token的认证机制",然后在说"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());
}
}
Run Code Online (Sandbox Code Playgroud)
您在评论中提到您无法控制正在安装的重叠绑定,因为它们来自第三方模块.如果是这种情况(我没有看到您的代码中发生了什么),出于安全原因,第三方可能不希望您执行您尝试执行的操作.例如,简单地绑定基于密码的机制可能会在整个应用程序中引入漏洞.可能值得尝试更好地了解第三方打算如何使用其模块.
另一个不理想但可以用于某些用例的选项是使用两个完全独立的Injector实例,每个实例具有一个绑定.然后,您手动将所需的实例直接传递给UI和API代码.这在一定程度上违背了Guice的目的,但并不总是错误的决定.利用孩子Injector小号可以使这种痛苦少.
另外,您的"示例代码"非常庞大,可能超过90%与此问题无关.将来请花点时间创建一个只包含与手头问题相关的代码的SSCCE.没有人会筛选100多个Java文件和7,300多行代码来理解你的问题.这不仅会让那些试图帮助您的人更容易,而且只是尝试创建一个证明问题的SSCCE通常足以帮助您自己理解和解决问题.
| 归档时间: |
|
| 查看次数: |
4831 次 |
| 最近记录: |