Можно ли предложить Guice вызвать некоторый метод (т. Е. Init()) после , инициализирующий объект заданного типа?Метод инициализации вызова Guice после создания объекта
Я смотрю на функциональность подобной @PostConstruct аннотации в EJB 3.
Можно ли предложить Guice вызвать некоторый метод (т. Е. Init()) после , инициализирующий объект заданного типа?Метод инициализации вызова Guice после создания объекта
Я смотрю на функциональность подобной @PostConstruct аннотации в EJB 3.
На самом деле, это возможно.
Для того, чтобы получить функциональность, вы должны указать TypeListener
. Что-то вдоль линий ниже в вашем определении модуля:
bindListener(Matchers.subclassesOf(MyInitClass.class), new TypeListener() {
@Override
public <I> void hear(final TypeLiteral<I> typeLiteral, TypeEncounter<I> typeEncounter) {
typeEncounter.register(new InjectionListener<I>() {
@Override
public void afterInjection(Object i) {
MyInitClass m = (MyInitClass) i;
m.init();
}
});
}
});
Также можно использовать GuicyFruit, который утверждает, что поддерживает @PostConstruct (см. Http://code.google.com/p/guiceyfruit /), и пока он не отвечает на этот вопрос, я думаю, стоит упомянуть, что если вы (исключительно) используете инъекцию конструктора, вам не нужны такие функциональные возможности, как вы можете выполнить всю инициализацию в конструкторе. – Eelco
спас мой день. @PostConstruct не поддерживается guiceyfruit еще –
Matchers.subclassesOf (MyInitClass.class) фактически приводит к ошибке времени компиляции: «Метод bindListener ( Супер TypeLiteral >> Сличитель, TypeListener) в типе AbstractModule не применяется для аргументов (Matcher
guiceyfruit делает то, что вы после того, как для методов, аннотированных @PostConstruct
или реализации весны InitializingBean
. Также можно написать своих собственных слушателей, чтобы это сделать. Вот пример, который вызывает общедоступный метод init()
после создания объектов.
import com.google.inject.*;
import com.google.inject.matcher.*;
import com.google.inject.spi.*;
public class MyModule extends AbstractModule {
static class HasInitMethod extends AbstractMatcher<TypeLiteral<?>> {
public boolean matches(TypeLiteral<?> tpe) {
try {
return tpe.getRawType().getMethod("init") != null;
} catch (Exception e) {
return false;
}
}
public static final HasInitMethod INSTANCE = new HasInitMethod();
}
static class InitInvoker implements InjectionListener {
public void afterInjection(Object injectee) {
try {
injectee.getClass().getMethod("init").invoke(injectee);
} catch (Exception e) {
/* do something to handle errors here */
}
}
public static final InitInvoker INSTANCE = new InitInvoker();
}
public void configure() {
bindListener(HasInitMethod.INSTANCE, new TypeListener() {
public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
encounter.register(InitInvoker.INSTANCE);
}
});
}
}
Спасибо за хороший пример, просто интересно, возвращает ли getMethod ("") значение null, потому что, когда он не находит указанный метод, он выдает NoSuchMethodException, и javadoc также не комментирует это. – zeratul021
Мне нравится http://code.google.com/p/mycila/wiki/MycilaGuice. Это поддерживает Guice 3, кроме http://code.google.com/p/guiceyfruit.
Примечание: mycila-guice 3.6 работает только с Guice 4.0, но не 4.1; см. https://github.com/mycila/guice/issues/11. – vorburger
Вы можете просто добавить аннотацию @Inject
к вашему методу init()
. Он будет запущен автоматически после создания объекта.
Проблема заключается в том, что этот подход не работает, если у вас есть необязательные зависимости, потому что нет способа рассказать о причинах вызова метода init() как последнего метода, насколько я знаю. Имхо им нужна поддержка @PostConstruct. –
Я использую инъекцию конструктора, где мне нужно сделать некоторые элементы инициализации, которые зависят от других зависимостей. –
@OrtwinAngermeier, если я правильно вас понимаю, вы можете поместить аннотацию '@ Inject' на свой конструктор _and_ по методу init. –
GWizard включает в себя модуль (gwizard-services
), который предоставляет услуги Guava в формате, удобном для Guice. Сервисы Guava предоставляют вам управление жизненным циклом в параллельных потоках.
, к сожалению, похоже, авторы Guice не намерены добавить @PostConstruct https://github.com/google/guice/issues/62#issuecomment-115452493, который не сильно ограничивает применимость Guice (есть обходные пути, но они довольно многословны). Возможно, вы захотите изучить некоторые другие структуры, такие как Spring или JEE CDI (например, Weld). – arcuri82