2014-05-22 4 views
0

У меня есть несколько модулей с интерфейсами службы привязки к соответствующим типам, и я могу получить экземпляр с помощьюПолучение экземпляра с помощью строкового литерала с Google Guice

injector.getInstance(MyServiceInterface.class) 

Я хотел бы получить экземпляр, используя

injector.getInstance("MyServiceInterface") 

т.е. строкового литерала вместо типа класса

Как я могу добиться этого?

Чтобы уточнить мой вопрос: я могу получить объект Class из строкового литерала с помощью вызова Class.forName(literal), а затем использовать его для извлечения экземпляра с помощью injector.getInstance(clsInstance).

После получения экземпляра, который я получаю в интерфейсе базового сервиса, мне нужно использовать отражение для вызова метода объекта службы.

так Обслуживание серв = injector.getInstance (MyCustomService.class)

Теперь мне нужно вызвать myCustomMethod(), присутствующий в MyCustomService посредством отражения, так как это Вызывающий является универсальным и предназначен для работы с несколькими службами, не будучи в курсе их фактического типа.

Мне также понадобятся перехватчики методов, настроенные на интерфейсах служб, которые будут прозрачно вызываться при обратном вызове метода в этом экземпляре.

ответ

1

Хотя я не уверен, что есть функциональность для встроенного в Guice, вы можете попробовать получить соответствующий объект Class<?>.

Что-то вдоль линий:

Class<?> myServiceInterfaceClass = Class.forName("path.to.MyServiceInterface"); 
injector.getInstance(myServiceInterfaceClass); 

Это, однако требует, чтобы текущий загрузчик классов доступа к этому определенному классу и т.д.

+0

Да я знаю этот вариант, но хотел бы знать, если есть решение в Сам Guice – Gautam

+0

В Guice нет решения. –

+0

Проблема заключается в том, что invoker является общим и не получит экземпляр в производном интерфейсе, скорее получит экземпляр в качестве базового типа. На этом мне нужно вызвать операцию через отражение. Я хочу знать, если это нарушит семантику Guice и если она вызовет метод перехватчиков на интерфейсе службы соответственно – Gautam

1

Это не может быть сделано в Guice ... потому что это не может быть, период! Подумайте об этом, допустим, у вас есть два одинаковых имени класса в разных пакетах. Какой класс вы бы создали?

Таким образом, по крайней мере, Строка должна иметь полное имя класса, например. вместо Integer было бы java.lang.Integer.


However, if you know which classes you want to support in advance, you can use a MapBinder.

Tweaking их примеру, чтобы соответствовать вашему использования:

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); 
+0

, так как интерфейс уже привязан к определенному иммону, мы знаем, какой тип impl должен использоваться. Задача для меня - получить экземпляр impl, когда я предоставляю service.interface как строковый литерал. Я думаю об использовании провайдера, который может предоставить мне объект класса взамен для имени класса, которое я могу использовать в файле injector.getInstance. Я не думаю, что пример MapBinder подходит в этом случае – Gautam

Смежные вопросы