Is it possible to tell Guice to call some method (i.e. init()) after instantinating an object of given type?
I look for functionality similar to @PostConstruct annotation in EJB 3.
Is it possible to tell Guice to call some method (i.e. init()) after instantinating an object of given type?
I look for functionality similar to @PostConstruct annotation in EJB 3.
Actually, it is possible.
You need to define a TypeListener
to get the functionality going. Something along the lines of the following in your module definition:
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();
}
});
}
});
guiceyfruit does what you're after for methods annotated with @PostConstruct
or implementing spring's InitializingBean
. It's also possible to write your own listeners to do this. Here's an example that calls a public init()
method after objects are created.
import com.google.inject.*;
import com.google.inject.matcher.*;
import com.google.inject.spi.*;
public class MyModule extends AbstractModule {
static class HasInitMethod extends AbstractMatcher> {
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 void hear(TypeLiteral type, TypeEncounter encounter) {
encounter.register(InitInvoker.INSTANCE);
}
});
}
}