Is there a way to have guice call a init() method after it has instantiated a singleton? Calling init() inside the constructor is not an option since init() could be overriden by a subclass.
            Asked
            
        
        
            Active
            
        
            Viewed 6,188 times
        
    2 Answers
10
            
            
        You can annotate a method in your module with @Inject and then request injection on the module:
class MyModule extends AbstractModule {
  @Override public void configure() {
    requestInjection(this);
  }
  @Inject void initMyClass(MyClass instance) {
     instance.init();
  }
}
 
    
    
        Community
        
- 1
- 1
 
    
    
        Andy Turner
        
- 137,514
- 11
- 162
- 243
3
            You can use `@PostConstruct' in guice when you use the mycila/jsr250 extension. This will cause your init() method to be called right after instantiation.
@PostConstruct
void init() {
     // ...
}
If you do not can/want to add 3rd party libs for this, I wrote a simple postconstruct module for this as well a while ago:
public enum PostConstructModule implements Module, TypeListener {
INSTANCE;
@Override
public void configure(final Binder binder) {
    // all instantiations will run through this typeListener
    binder.bindListener(Matchers.any(), this);
}
/**
 * Call postconstruct method (if annotation exists).
 */
@Override
public <I> void hear(final TypeLiteral<I> type, final TypeEncounter<I> encounter) {
    encounter.register(new InjectionListener<I>() {
        @Override
        public void afterInjection(final I injectee) {
            for (final Method postConstructMethod : filter(asList(injectee.getClass().getMethods()), MethodPredicate.VALID_POSTCONSTRUCT)) {
                try {
                    postConstructMethod.invoke(injectee);
                } catch (final Exception e) {
                    throw new RuntimeException(format("@PostConstruct %s", postConstructMethod), e);
                }
            }
        }
    });
   }
  }
 
    
    
        Jan Galinski
        
- 11,768
- 8
- 54
- 77
- 
                    Can you describe what the advantages of this approach are over mine? It seems like there must be a good reason to use extensions when I'd have thought it was easier to use the base library. (I'm not snarking, I am genuinely interested) – Andy Turner Sep 21 '15 at 06:06
- 
                    Hi Andy. As you can see, you basically only need a TypeListener, so this is "base library" functionality. Injecting into modules is dangerous. If you rely on injectors inside your module, you may get complex runtime/timing dependencies, where it might be that your code runs perfectly until you need one more binding that requires the injection to take place before resolving the instance ... I went down that road once and ended up having "if != null" statements around my providers so I could react on runtime dependencies. This may work in some cases, but a rule of thumb: don't do it. – Jan Galinski Sep 21 '15 at 07:47
