我有多个模块,服务接口绑定到相应的类型,我可以使用
获取实例injector.getInstance(MyServiceInterface.class)
我想使用
检索实例injector.getInstance("MyServiceInterface")
即。字符串文字而不是类类型
我怎样才能做到这一点?
进一步阐述我的问题 - 我可以使用Class.forName(literal)
调用从字符串文字中检索Class对象,然后使用它来检索具有injector.getInstance(clsInstance)
的实例。
在检索我在基本服务类型接口中收到的实例后,我需要使用反射来调用服务对象的方法。
所以Service serv = injector.getInstance(MyCustomService.class)
现在我需要通过反射来调用MyCustomService中存在的myCustomMethod(),因为这个调用程序是通用的,用于处理多个服务而不知道它们的实际类型。
当我反复调用此实例上的方法时,我还需要透明地调用服务接口上配置的Method拦截器。
答案 0 :(得分:1)
虽然我不确定Guice本身是否具有内置功能,但您可以尝试亲自获取相关的Class<?>
对象。
有些事情:
Class<?> myServiceInterfaceClass = Class.forName("path.to.MyServiceInterface");
injector.getInstance(myServiceInterfaceClass);
但是,这需要当前的类加载器可以访问该特定的类等。
答案 1 :(得分:1)
这不能在Guice中完成......因为它无法完成,期间!考虑一下,假设你在不同的包中有两个相同的类名 。你会实例化哪一堂课?
所以至少String必须具有完全限定的类名,例如而不是Integer
,它会有java.lang.Integer
。
However, if you know which classes you want to support in advance, you can use a MapBinder.
调整他们的示例以匹配您的用例:
public class ServiceModule extends AbstractModule {
protected void configure() {
MapBinder<String, MyServiceInterface> mapbinder
= MapBinder.newMapBinder(binder(), String.class, MyServiceInterface.class);
mapbinder.addBinding("MyServiceInterface").to(MyServiceImpl.class);
bind(MyServiceInterface.class).to(MyServiceImpl.class);
}
}
现在你可以这样注射:
class ServiceManager {
@Inject
public ServiceManager(Map<String, MyServiceInterface> services) {
MyServiceInterface service = stacks.get("MyServiceInterface");
// etc.
}
}
请注意,当您致电inj.getInstance()
时,您必须知道您要创建的对象的返回类型,除非您打算这样做:
Object foo = inj.getInstance(myString);