Czy można powiedzieć Guice, aby wywołała jakąś metodę (tj. Init()) po zainicjowaniu obiektu danego typu przez ?Metoda inicjacji wywołania Guice po zainicjowaniu obiektu
patrzę na funkcjonalność podobną do @PostConstruct adnotacji w EJB 3.
Czy można powiedzieć Guice, aby wywołała jakąś metodę (tj. Init()) po zainicjowaniu obiektu danego typu przez ?Metoda inicjacji wywołania Guice po zainicjowaniu obiektu
patrzę na funkcjonalność podobną do @PostConstruct adnotacji w EJB 3.
Faktycznie, jest to możliwe. Aby uzyskać funkcjonalność, należy zdefiniować TypeListener
. Coś wzdłuż linii następujących w definicji modułu:
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();
}
});
}
});
Możesz także użyć GuicyFruit, który twierdzi, że wspiera @PostConstruct (zobacz http://code.google.com/p/guiceyfruit /), i chociaż nie odpowiada na to pytanie, myślę, że warto wspomnieć, że jeśli (wyłącznie) korzystasz z wtrysku konstruktora, nie potrzebujesz takiej funkcjonalności, jak możesz wykonać całą inicjalizację w konstruktorze. – Eelco
zapisał mój dzień. @PostConstruct nie jest obsługiwany przez guiceyfruit jeszcze –
Matchers.subclassesOf (MyInitClass.class) faktycznie spowoduje błąd podczas kompilacji: "Metoda bindListener (Matcher Super TypeLiteral >>, TypeListener) w typie AbstractModule nie ma zastosowania dla argumentów (Matcher
guiceyfruit robi to, co jesteś po metod opatrzone @PostConstruct
lub wykonawczych sprężyny InitializingBean
. Możliwe jest również napisanie własnych słuchaczy, aby to zrobić. Oto przykład, który wywołuje publiczną metodę init()
po utworzeniu obiektów.
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);
}
});
}
}
Dzięki za miły przykład, zastanawiam się, czy getMethod ("") kiedykolwiek zwróci wartość null, ponieważ gdy nie znajdzie określonej metody, generuje NoSuchMethodException, a javadoc również tego nie komentuje. – zeratul021
Podoba mi się http://code.google.com/p/mycila/wiki/MycilaGuice. To obsługuje Guice 3, inne niż http://code.google.com/p/guiceyfruit.
Notatka mycila-guice 3.6 działa tylko z Guice 4.0, ale nie 4.1, jeszcze; zobacz https://github.com/mycila/guice/issues/11. – vorburger
Możesz po prostu dodać adnotację @Inject
do swojej metody init()
. Uruchomi się automatycznie po utworzeniu obiektu.
Problem w tym, że to podejście nie działa, jeśli masz opcjonalne zależności, ponieważ nie ma sposobu, aby powiedzieć guice, aby wywołać twoją metodę init() jako ostatnią metodę, o ile wiem. IMHO potrzebują wsparcia @PostConstruct. –
Korzystam z wtrysku konstruktora, gdzie muszę wykonać pewne czynności inicjujące, które zależą od innych zależności. –
@ OrtwardenAngermeier, jeśli dobrze cię rozumiem, możesz umieścić adnotację '@ Inject' na swoim konstruktorze _ i _ na swojej metodzie init. –
GWizard zawiera moduł (gwizard-services
), który zapewnia usługi Guava w formacie przyjaznym Guice. Usługi Guava umożliwiają zarządzanie cyklem życia w równoległych wątkach.
niestety, wygląda na to autorzy Guice nie mają zamiaru dodawać @PostConstruct https://github.com/google/guice/issues/62#issuecomment-115452493, który ma silnie ogranicza stosowalność Guice (istnieją rozwiązania, ale te są dość szczegółowe). Możesz zajrzeć do innych frameworków, takich jak Spring lub JEE CDI (np. Weld). – arcuri82