2010-01-19 213 views
53

是否可以告诉Guice在 之后调用某种方法(即init())来传递给定类型的对象?Guice在初始化对象后调用初始化方法

我找类似的EJB以@PostConstruct注释3.

+0

不幸的是,它看起来像吉斯的作者并没有刻意添加@PostConstruct https://github.com/google/guice/issues/62#issuecomment-115452493,这并强烈限制的适用性Guice(有解决方法,但这些都非常冗长)。您可能需要查看其他一些框架,例如Spring或JEE CDI(例如Weld) – arcuri82 2016-12-26 19:21:24

回答

28

其实功能,这是可能的。

您需要定义一个TypeListener才能使功能正常运行。沿着以下的在你的模块定义线的东西:

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(); 
      } 
     }); 
    } 
}); 
+4

另外一种选择是使用GuicyFruit,它声称支持@PostConstruct(请参阅http://code.google.com/p/guiceyfruit /),虽然它没有回答这个问题,但我认为值得一提的是,如果你(仅)使用构造器注入,你不需要这样的功能,你可以在构造器中完成所有的初始化。 – Eelco 2010-02-28 09:19:56

+0

救了我一天。 @PostConstruct目前还不支持guiceyfruit – 2010-03-10 09:41:12

+7

Matchers.subclassesOf(MyInitClass.class)实际上会导致编译时错误: “AbstractModule类型中的方法bindListener(Matcher <?super TypeLiteral >,TypeListener)不适用(Matcher ,new TypeListener(){})“ 我想你必须扩展AbstractMatcher才能使你的代码工作 – Andrey 2012-02-28 16:25:21

6

guiceyfruit确实是想与注解的方法后是什么@PostConstruct或实施春天的InitializingBean。也可以编写自己的监听器来执行此操作。这是一个在创建对象后调用公共init()方法的示例。

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

感谢您的好例子,只是想知道如果getMethod(“”)返回null,因为当它没有找到指定的方法时,它会抛出NoSuchMethodException,并且javadoc也不会对此做出任何评论。 – zeratul021 2010-11-21 02:12:37

49

您可以将@Inject注释添加到您的init()方法中。对象实例化后它会自动运行。

+9

问题是,如果你有可选的依赖关系,这种方法不起作用,因为根据我所知,没有办法告诉guice调用你的init()方法作为最后一个方法。恕我直言,他们需要@PostConstruct支持。 – 2012-04-04 13:12:18

+0

我正在使用构造函数注入,我必须做一些取决于其他依赖关系的初始化东西。 – 2014-11-04 15:27:30

+1

@OrtwinAngermeier,如果我正确理解你的话,你可以在你的构造函数_and_的init方法中放入一个@Inject注解。 – 2015-10-02 20:12:15