Guice call initialization method after creating an object

Is it possible to tell Guice to call some method (i.e. init ()) after initializing an object of this type?

I am looking for functionality similar to @PostConstruct annotation in EJB 3.

+57
guice postconstruct init
Jan 19 '10 at 12:18
source share
7 answers

In fact, it is possible.

You need to define a TypeListener to get the functionality. Something like 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(); } }); } }); 
+33
Jan 19
source share

You can simply add the @Inject annotation to your init() method. It will start automatically after creating the object.

+55
May 20 '11 at 14:01
source share

guiceyfruit does what you need for methods annotated with @PostConstruct or an implementation of spring InitializingBean . You can also write your own listeners for this. Here is an example that calls the public init() method after creating the objects.

 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); } }); } } 
+7
Jan 19
source share
+7
Apr 15 '11 at 10:13
source share

GWizard includes a module ( gwizard-services ) that provides Guava services in a format convenient for Guice. Guava services provide you with lifecycle management in parallel threads.

https://github.com/stickfigure/gwizard

+1
Jan 22 '15 at 2:22
source share

In case you need to initialize an object using other objects, and after both are ready (which is the case if you need to register one object with another, and they also depend on each other), you can easily do this in the following way:

 public final class ApplicationModule extends AbstractModule { @Override protected void configure() { requestStaticInjection(ApplicationModule.class); } @Inject static void injectApplication( ReslSession reslSession, Set<Saga> sagas, Set<Reaction> reactions ) { sagas.forEach(reslSession::registerSaga); reactions.forEach(reslSession::registerReaction); } } 
0
Apr 03 '19 at 10:20
source share

If you want to call the method after creating the instance, this means that calling the method after construction is actually the stage of creating the instance. In this case, I would recommend an abstract factory design template to solve this problem. The code might look something like this:

 class A { public A(Dependency1 d1, Dependency2 d2) {...} public postConstruct(RuntimeDependency dr) {...} } interface AFactory { A getInstance(RuntimeDependency dr); } class AFactoryImpl implements AFactory { @Inject public AFactoryImpl(Dependency1 d1, Dependency2 d2) {...} A getInstance(RuntimeDependency dr) { A a = new A(d1, d2); a. postConstruct(dr); return a; } } // in guice module bind(AFactory.class).to(AFactoryImpl.class) 
0
May 14 '19 at 9:47
source share



All Articles