使用Google Guice的字符串文字检索实例

时间:2014-05-22 13:14:51

标签: java guice

我有多个模块,服务接口绑定到相应的类型,我可以使用

获取实例
injector.getInstance(MyServiceInterface.class) 

我想使用

检索实例
injector.getInstance("MyServiceInterface")

即。字符串文字而不是类类型

我怎样才能做到这一点?

进一步阐述我的问题 - 我可以使用Class.forName(literal)调用从字符串文字中检索Class对象,然后使用它来检索具有injector.getInstance(clsInstance)的实例。

在检索我在基本服务类型接口中收到的实例后,我需要使用反射来调用服务对象的方法。

所以Service serv = injector.getInstance(MyCustomService.class)

现在我需要通过反射来调用MyCustomService中存在的myCustomMethod(),因为这个调用程序是通用的,用于处理多个服务而不知道它们的实际类型。

当我反复调用此实例上的方法时,我还需要透明地调用服务接口上配置的Method拦截器。

2 个答案:

答案 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);