我正在使用 Guice 开发一个小型 Web 框架。我有一个 Router 对象,一旦初始化,就会公开一个 getControllerClasses() 方法。我必须遍历所有这些动态返回的类以使用 Guice 绑定(bind)()它们。
我绑定(bind)路由器:
bind(IRouter.class).to(Router.class);
但是,我怎样才能在一个模块中获得绑定(bind)的路由器实例,所以我也可以绑定(bind)它的 getControllerClasses() 方法返回的类呢?
我能够在模块中获取 Router 实例的唯一方法是将此实例绑定(bind)到第一个模块中,然后将其注入(inject)第二个模块中,在 setter 上使用 @Inject :
模块 1
bind(IRouter.class).to(Router.class);
Module2 module2 = Module2();
requestInjection(module2);
install(module2);
模块二
@Inject
public void setRouter(IRouter router)
{
Set<Class<?>> controllerClasses = router.getControllerClasses();
for(Class<?> controllerClass : controllerClasses)
{
bind(controllerClass);
}
}
方法被调用,Router 实例初始化良好,但是 Controller 类的绑定(bind)失败!在 Guice 生命周期的这一步,module2 的 binder 实例似乎为 NULL。
如何绑定(bind)动态获取的类,这些类已由已绑定(bind)的对象返回?
最佳答案
此时 Binder 为空,因为 Guice 在调用 configure() 之前设置了 binder。在 Guice 调用模块的 configure() 方法之外,没有活页夹。请记住 Module
只是一个配置文件,它配置了Injector
创建一个时的行为。requestInjection
它的行为不像你想象的那样——也就是说,它不会立即绑定(bind)你传入的实例的字段。相反,你告诉它在有人创建 Injector
时立即注入(inject)字段和方法。 .在创建 Injector 之前,不会将任何内容注入(inject)到传递的实例中。
如果您的路由器没有需要 Guice 的依赖项,那么只需创建一个 new Router()
并将其作为构造函数参数传递到您的模块中。然后你可以遍历你的控制类并绑定(bind)它们,还有bind(Router.class).toInstance(myRouter);
.
但是,如果您的路由器确实依赖于其他模块,那么您可以使用 child Injector .首先,创建一个 Injector,从中获取一个 Router 实例,然后将该 Router 实例传递给另一个绑定(bind)其控制类的 Module。突然之间,您将拥有一个模块(我们称之为 controlClassesModule),您可以执行以下操作:
newInjector = originalInjector.createChildInjector(controllingClassesModule);
然后,您的
newInjector
将从您的 originalInjector
继承绑定(bind)以及路由器指定的所有控制类。希望有帮助!
关于吉斯 : How to bind classes that are dynamically obtained by an already binded object?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12774020/