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 annot
Based on Geoff's answer you can "make callable" @PostConstruct method:
public class GuiceExample {
@Inject
private IDataManager dataManager;
public GuiceExample() {
System.out.println("Constructor");
}
@PostConstruct
private void init() {
dataManager.printData();
}
public static void main(String[] args) {
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(IDataManager.class).to(DataManager.class);
bindListener(HasPostConstructAnnotationMatcher.INSTANCE, new TypeListener() {
@Override
public void hear(TypeLiteral type, TypeEncounter encounter) {
encounter.register(PostConstructAnnotationInvoker.INSTANCE);
}
});
}
});
GuiceExample example = injector.getInstance(GuiceExample.class);
}
private static class HasPostConstructAnnotationMatcher extends AbstractMatcher> {
private static final HasPostConstructAnnotationMatcher INSTANCE = new HasPostConstructAnnotationMatcher();
@Override
public boolean matches(TypeLiteral> t) {
return Arrays.stream(t.getRawType().getDeclaredMethods()).anyMatch(GuiceExample::hasPostConstructAnnotation);
}
}
private static boolean hasPostConstructAnnotation(Method method) {
Annotation[] declaredAnnotations = method.getAnnotations();
return Arrays.stream(declaredAnnotations).anyMatch(a -> a.annotationType().equals(PostConstruct.class));
}
private static class PostConstructAnnotationInvoker implements InjectionListener
Also, you can have multiple @PostConstruct method but you will not know in which order they are going to be invoked:
@PostConstruct
private void init() {
dataManager.printData();
}
@PostConstruct
private void init2() {
System.out.println("Other init method");
}