#java #dynamic #proxy #guice
#java #динамический #прокси #guice
Вопрос:
Я ищу решение для привязки любого подинтерфейса интерфейса тегов к экземпляру, созданному динамическим прокси-сервером Java. Динамический прокси-сервер знает, как реализовать каждый метод в подинтерфейсах. Проблема в том, что я хочу сделать это автоматически для всех запрошенных субинтерфейсов.
interface ITaggingInterface() {
}
interface ISubInterface extends ITaggingInterface {
String doSomething();
}
ISubInterface может быть реализован с помощью прокси:
ISubInterface si = (ISubInterface)Proxy.newProxyInstance(classloader, new Class<?>[]{ISubInterface.class}, invocationHandler);
Как мне настроить мой инжектор так, чтобы каждый раз, когда запрашивается вспомогательный интерфейс, он использовал динамический прокси для создания реализации.
Я знаю, что могу связать каждый подинтерфейс отдельно, но это то, чего я хочу избежать. Я ищу что-то похожее на:
bind(any-sub-interface).toProvider(provider-that-creates-proxy-instance);
Возможно ли это с помощью guice?
Ответ №1:
Я не верю, что это возможно так, как вы ищете. По сути, привязки Guice похожи на Map<Key, Provider>
. Это затрудняет привязку «любого типа с этой аннотацией», «любого подтипа этого типа» или других подобных привязок, подобных сопоставлению.
Если вы согласны с использованием метода / ввода поля и пользовательской аннотации вместо @Inject, вы можете попробовать использовать пользовательскую инъекцию, которая позволит вам проверять введенные классы и манипулировать ими по мере необходимости так, как это делает приведенная выше ссылка с @InjectLogger .
Помимо реструктуризации ваших требований, мое личное решение было бы примерно таким:
/** Injectable. */
class TaggingInterfaceFactory {
/** Guice can always inject the injector. */
@Inject Injector injector;
<T> T getInstanceOrProxy(Class<T> clazz) {
if (clazz.isAssignableFrom(ITaggingInterface.class)) {
return createYourProxyHere(clazz);
} else {
return injector.getInstance(clazz);
}
}
}