2014-10-17 72 views
0

我正尝试使用Java EE 6构建应用程序。开发是在TomEE 1.7上完成的。由于各种原因,我必须通过服务生产者创建大部分CDI托管对象。但是,当我这样做时,不会调用已创建的Bean的注释方法@PostConstruct。如果我将服务生产者排除在外,并让CDI通过其构造函数直接创建对象,则它会被调用。这是正常的,或者是它的CDI提供的使用服务生产者的CDI PostConstruct

感谢

回答

1

这是正常行为的错误TomEE自带(开放WebBeans的)。当bean被容器初始化时,调用@PostConstruct方法。见Weld Reference

简化只是一个小的事情在这个顺序发生:

  • 首先,容器调用bean的构造函数(默认构造函数或一个注释@Inject),来获得实例
    这个bean。

  • 接下来,容器初始化bean的所有注入字段的值。

  • 接下来,容器调用bean的所有初始化方法(调用顺序不可移植,不要依赖它)。
  • 最后,调用@PostConstruct方法(如果有的话)。

然而,在制作方法的情况下,你有充分的控制,对象是如何创建的,所以你可以自行调用任何需要的方法。注意,在生产者方法中,对象通常是使用new创建的,因此带注释的字段不会被初始化。再次检查producer method documentation可能的解决方案(注入生产者方法,@New

+0

我把它直接在生产者调用@PostConstruct方法工作。我以前曾尝试过,但无法完成,因为该方法取决于其他注入生产的其他豆类的方法。发现生产者方法的论点填补了这个空白。 – 2014-10-20 06:52:05

0

似乎不好的做法使用生产者的一切 - 为什么你使用生产者,如果你的类用@PostConstruct注释?

这样做的一种方法是在生产者方法中使用创建上下文来提供引用,然后在该引用上调用post构造。下面是一些示例代码,从Apache DeltaSpike,一套CDI扩展采取:

BeanProvider

BeanManager beanManager = getBeanManager(); 

    CreationalContext creationalContext = beanManager.createCreationalContext(null); 

    AnnotatedType annotatedType = beanManager.createAnnotatedType(instance.getClass()); 
    InjectionTarget injectionTarget = beanManager.createInjectionTarget(annotatedType); 
    injectionTarget.inject(instance, creationalContext); 
    injectionTarget.postConstruct(instance); 
+0

我使用了一个生产者,因为在UI bean中注入的大多数组件都有两种风格,创建的内容取决于运行时参数。你的示例代码似乎将注入的bean的后期构建与注入点相关联,因此对于多个注入点,我需要对哪个注入点调用post构建进行一些管理。 – 2014-10-20 06:30:44

+0

我不确定你的意思。是什么让你想到这个?例如,这是一个生产者方法的内容,一旦你实例化了你的实例。 'InjectionTarget'只是一个CDI中的API,允许您在托管对象上调用PostConstruct或PreDestroy方法。 – 2014-10-20 10:35:02

+0

对不起,我的解释只是猜测。我假设InjectionTarget表示创建的实例注入的bean,并且代码在注入发生时运行。我的错。当我有一段时间的时候,我会仔细看看DeltaSpike,这似乎是一个有价值的投资 – 2014-10-22 07:09:38