后期创建初始化guice singleton

时间:2015-09-17 16:37:14

标签: java guice code-injection

有没有办法让guice在实例化单例后调用init()方法?在构造函数中调用init()不是一个选项,因为init()可以被子类覆盖。

2 个答案:

答案 0 :(得分:9)

您可以使用@Inject在模块中注释方法,然后在模块上请求注入:

class MyModule extends AbstractModule {
  @Override public void configure() {
    requestInjection(this);
  }

  @Inject void initMyClass(MyClass instance) {
     instance.init();
  }
}

另见https://stackoverflow.com/a/24480630/3788176

答案 1 :(得分:2)

使用mycila/jsr250 extension时,可以在guice中使用`@PostConstruct'。这将导致在实例化后立即调用init()方法。

@PostConstruct
void init() {
     // ...
}

如果您不能/想要为此添加第三方库,我之前为此写了一个简单的postconstruct module

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);
                }
            }
        }
    });
   }
  }