我需要一些帮助来使用guice。 我的项目在这里:https://github.com/Romain-P/kalibro/blob/master/realm/src/org/kalibro/core/Main.java
我的问题:我需要在这个Main.java中替换3个注射器,只需要1个注射器。
我的申请是分开的: LoginServer和WorldServers。 你只需要1个realmServer和一些WorldServers。
现在,我刚刚创建了realmServer。你有: - RealmManager(管理玩家< - > loginServer) - ExchangeManager(管理世界< - > loginServer)
他们接受联系,他们用netty创建客户。 RealmManager& ExchangeManager扩展了NetworkService。
NetworkService是一个abstractClass,可以根据需要创建所有管理器。想象一下,如果我以后想要创建与webServer说话的shopManager。
请参阅代码:https://github.com/Romain-P/kalibro/tree/master/realm/src/org/kalibro/network/netty
现在,我的Main.java有3个注射器,但我需要只有1个。 这确实有效!但我认为它没有清理,所以我需要只有一个注射器。
Main.java
[...]
Injector exchangeInjector = Guice.createInjector(new ExchangeModule());
Injector realmInjector = Guice.createInjector(new RealmModule());
try {
log.info("initializing exchange");
exchangeInjector.getInstance(ExchangeManager.class).run(config.getExchangePort());
log.info("initializing server");
realmInjector.getInstance(RealmManager.class).run(config.getRealmPort());
} catch(Exception e) {
log.error("Can't start application", +e.getMessage());
System.exit(1);
}
模块:
public class RealmModule extends AbstractModule {
protected void configure() {
install(new NetworkModule());
bind(NetworkService.class).to(RealmManager.class);
}
}
//the same for ExchangeModule..
答案 0 :(得分:3)
Guice injector有...数组作为参数:
Guice.createInjector(Module... modules);
所以你可以这样做:
Guice.createInjector(new ExchangeModule(), new RealmModule());
如果存在一些冲突,您可以尝试binding annotations或untargetted bindings。
编辑:
这可能会说明如何避免冲突:
bind(NetworkService.class).annotatedWith(Exchange.class).to(ExchangeManager.class);
bind(NetworkService.class).annotatedWith(Realm.class).to(RealmManager.class);
然后:
@Inject
@Exchange
private NetworkService exchangeService;
编辑2:
我认为最大的问题是您启动NetworkService的方式。你可以把它变成一个抽象类,然后写出类似的东西:
public class ExchangeHandler extends AbstractHandler {
@Inject
ExchangeHandler(@Exchange NetworkService service) {
super(service);
}
}
除了获取NetworkService实例之外,您希望有2个不同的实例使用完全相同的代码。有几种方法可以做到这一点,但这个方法似乎是目前最具可读性的。或者,您可以考虑使用Inversion of Control来传递您目前所需的NetworkService,而不是为Exchange
和Reaml
经理创建2个不同的对象树。
class ClassUsingManagers {
@Inject
ClassUsingManagers(
@Exchange NetworkService exchangeService,
@Realm NetworkService realmService,
NetworkServiceHandler handler) {
handler.actionForService(exchangeService);
handler.actionForService(realmService);
}
}
或者如果您只想启动它们并运行一个方法(初始化其他所有方法):
Multibinder serviceSet = Multibinder.newSetBinder(binder(), NetworkService.class);
serviceSet.addBinding().asEagerSingleton();
然后:
class ClassUsingManagers {
@Inject
ClassUsingManagers(
Set<NetworkService> services,
NetworkServiceHandler handler) {
for(NetworkService service : services)
handler.actionForService(service);
}
}
其他方法需要您将Guice Multbinding插件安装到Guice。
答案 1 :(得分:0)
我建议使用绑定annotation来区分NetworkService的注入,可能是:
@ManagesExchange NetworkService
@ManagesRealm NetworkService