Guice:如何绑定由已经绑定的对象动态获取的类?

ele*_*ype 5 guice guice-servlet

我正在使用Guice开发一个小型Web框架.我有一个Router对象,一旦初始化,就会公开一个getControllerClasses()方法.我必须使用Guice将所有动态返回的类循环到bind()它们.

我绑定路由器:

bind(IRouter.class).to(Router.class);
Run Code Online (Sandbox Code Playgroud)

但是,如何在Module中获取绑定的Router实例,这样我还可以绑定其getControllerClasses()方法返回的类?

我能够在模块中获取路由器实例的唯一方法是在第一个模块中绑定此实例,然后在setter上使用@Inject将其注入第二个模块:

第1单元

bind(IRouter.class).to(Router.class);

Module2 module2 = Module2();
requestInjection(module2);
install(module2); 
Run Code Online (Sandbox Code Playgroud)

第2单元

@Inject
public void setRouter(IRouter router)
{
    Set<Class<?>> controllerClasses = router.getControllerClasses();
    for(Class<?> controllerClass : controllerClasses)
    {
        bind(controllerClass);
    }
}
Run Code Online (Sandbox Code Playgroud)

调用该方法并初始化Router实例,但控制器类的绑定失败!在Guice生命周期的这一步,似乎module2 的binder实例是NULL.

如何绑定动态获取的类,这些类是否已由已绑定的对象返回?

Jef*_*ica 8

Binder在那时为空,因为Guice在调用configure()之前设置了绑定器.在Guice之外调用Module的configure()方法,没有绑定器.请记住,a Module只是一个配置文件,它可以配置Injector创建时的行为方式.

requestInjection不像你想象的那样 - 也就是说,它不会立即绑定你传入的实例的字段.相反,你告诉它在有人创建时尽快注入字段和方法Injector.在创建Injector之前,不会将任何内容注入到传递的实例中.

如果您的路由器没有需要Guice的依赖项,那么只需创建一个new Router()并将其作为构造函数参数传递给您的模块.然后你可以遍历你的控制类并绑定它们,以及bind(Router.class).toInstance(myRouter);.

但是,如果您的路由器确实依赖于其他模块,那么您可以使用子Injector.首先,创建一个Injector,从中获取一个Router实例,然后将该Router实例传递给另一个绑定其控制类的Module.突然你会有一个模块(我们称之为controlsClassesModule)你可以做以下事情:

newInjector = originalInjector.createChildInjector(controllingClassesModule);
Run Code Online (Sandbox Code Playgroud)

然后,您newInjector将继承您originalInjector和您指定的所有控制类的绑定.

希望有所帮助!