【问题标题】:Post creation initialization of guice singleton [duplicate]guice单例的创建后初始化[重复]
【发布时间】:2015-09-17 16:37:13
【问题描述】:

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

【问题讨论】:

    标签: java guice code-injection


    【解决方案1】:

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

    class MyModule extends AbstractModule {
      @Override public void configure() {
        requestInjection(this);
      }
    
      @Inject void initMyClass(MyClass instance) {
         instance.init();
      }
    }
    

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

    【讨论】:

      【解决方案2】:

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

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

      如果您不能/不想为此添加 3rd 方库,我不久前也为此写了一个简单的 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);
                      }
                  }
              }
          });
         }
        }
      

      【讨论】:

      • 你能描述一下这种方法比我有什么优势吗?当我认为使用基础库更容易时,似乎必须有充分的理由使用扩展。 (我不是在开玩笑,我真的很感兴趣)
      • 嗨,安迪。如您所见,您基本上只需要一个 TypeListener,因此这是“基础库”功能。注入模块是危险的。如果您依赖模块中的注入器,您可能会得到复杂的运行时/时序依赖关系,您的代码可能会完美运行,直到您需要一个需要在解析实例之前进行注入的绑定......我失败了那条路一次,最后在我的提供者周围有“if!= null”语句,这样我就可以对运行时依赖项做出反应。这在某些情况下可能有效,但经验法则是:不要这样做。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多