我正在使用Guice开发一个小型Web框架。我有一个 Router 对象,一旦初始化,就会公开一个 getControllerClasses()方法。我必须使用Guice将所有动态返回的类循环到bind()它们。
我绑定路由器:
bind(IRouter.class).to(Router.class);
但是,如何在模块中获取绑定的Router实例,所以我还可以绑定其 getControllerClasses()方法返回的类?
我能够在模块中获取路由器实例的唯一方法是在第一个模块中绑定此实例,然后在第二个模块中将其注入,在setter上使用@Inject:
第1单元
bind(IRouter.class).to(Router.class);
Module2 module2 = Module2();
requestInjection(module2);
install(module2);
第2单元
@Inject
public void setRouter(IRouter router)
{
Set<Class<?>> controllerClasses = router.getControllerClasses();
for(Class<?> controllerClass : controllerClasses)
{
bind(controllerClass);
}
}
调用该方法并初始化Router实例,但控制器类的绑定失败!在Guice生命周期的这一步,似乎module2的 binder 实例为NULL。
如何绑定动态获取的类,这些类是否已由已绑定的对象返回?
答案 0 :(得分:8)
Binder在那时为空,因为Guice在调用configure()之前设置了绑定器。在Guice之外调用Module的configure()方法,没有绑定器。请记住,Module
仅仅是一个配置文件,它会配置Injector
创建时的行为方式。
requestInjection
的行为与您认为的不同 - 也就是说,它不会立即绑定您传入的实例的字段。相反,您告诉它将字段和方法注入有人创建Injector
之后。在创建Injector之前,不会将任何内容注入到传递的实例中。
如果您的路由器没有需要Guice的依赖项,那么只需创建一个new Router()
并将其作为构造函数参数传递给您的模块。然后,您可以遍历控制类并绑定它们,还可以bind(Router.class).toInstance(myRouter);
。
但是,如果您的路由器确实依赖于其他模块,那么您可以使用child Injector。首先,创建一个Injector,从中获取一个Router实例,然后将该Router实例传递给另一个绑定其控制类的Module。突然你会有一个模块(我们称之为controlsClassesModule)你可以做以下事情:
newInjector = originalInjector.createChildInjector(controllingClassesModule);
然后,您的newInjector
将继承您originalInjector
的绑定以及路由器指定的所有控制类。
希望有所帮助!