控制EJB 3.1中的CDI启动

我是新来的,也是CDI世界的新手,我在工作中得到的第一项任务就是找到一种控制CDI上传的方法。

我们使用EJB 3.1CDI 1.0 ,并且因为它们由不同的容器控制,我们可以通过使用@Startup@Singleton注释来控制EJB Managed Beans的启动时间和顺序。

但是我在我的类中声明的@Inject CDI bean因为CDI容器尚未启动而变为null。

我已经尝试了几天来寻找解决方案,而我在这里找到的解决方案没有用(仍然是空的)。

我们正在使用Java EE 6并在WebSphere Application Server 8上运行该应用程序。

请问,如果你能帮我找到一种方法来控制内部和不管EJB的CDI上传?

这是一个示例代码:

 import javax.annotation.PostConstruct; import javax.ejb.Singleton; import javax.ejb.Startup; @Singleton @Startup public class BaseStartupLoader{ /** * Default constructor. */ @Inject @MyStartup BaseStartUp myStartup; private static Logger m_logger = LoggerFactory.getLogger(BaseStartupLoader.class); public BaseStartupLoader() { } @PostConstruct public void init(){ String applicationName = null; try { applicationName = myStartup.getClass().getName(); myStartup.load(); } catch (IllegalAccessException e) { m_logger.error("Faild to load data into preload system. "+e); } catch (InstantiationException e) { m_logger.error("Faild to load data into preload system. "+e); } catch (ClassNotFoundException e) { m_logger.error("Faild to load data into preload system - Class "+ applicationName + "Not found. "+e); } } } 

这是BaseStartup接口:

 public interface BaseStartUp { public void load() throws IllegalAccessException, InstantiationException, ClassNotFoundException; } 

资格赛和实施:

 @Retention(RetentionPolicy.RUNTIME) @Target ({ElementType.PARAMETER, ElementType.FIELD, ElementType.TYPE, ElementType.METHOD}) @Qualifier @Dependent public @interface MyStartup { } @MyStartup public class MyStartUpLoader implements BaseStartUp { @Inject SomeConfigLoader config; @Override public void load() throws IllegalAccessException, InstantiationException, ClassNotFoundException { conifg.init(); } } 

经过大量研究后,我从IBM的人员那里得到了一些帮助,因为我们正在使用WebSphere Application Server,我可以添加一个名为的JVM属性:

“com.ibm.ws.cdi.immediate.ejb.start”= true

在管理控制台中的WAS,他将确保一旦我在@Startup bean中获得EJB @PostConstruct方法,我创建的CDI容器就已经启动并且已经注入。

有用!!

以下是IBM站点中问题和解决方案的链接:

http://www-01.ibm.com/support/docview.wss?uid=swg1PM62774

也许仔细检查CDI实际上是否在应用程序所需的所有位置启用。 尝试将此代码添加到BaseStartupLoader作为实验:

 @Singleton @Startup public class BaseStartupLoader { @Inject @MyStartup BaseStartUp myStartup; @Inject private InjectionTest test; public static class InjectionTest {} } 

如果@PostConstructtest变量为null,则可能未在声明BaseStartupLoader的jar中启用CDI。

例如,如果说, BaseStartupLoader是在名为orange.jar的jar中声明的, BaseStartupLoader是在名为orange.jar的jar中yellow.jar ,那么这两个文件必须存在:

  • orange.jar!/META-INF/beans.xml
  • yellow.jar!/META-INF/beans.xml

如果通过META-INF/beans.xml在两个jar子中正确启用CDI,那么这是容器中的错误。 在调用@PostConstruct之前,需要完成所有@Inject点(对于支持CDI的jar)。 无论是否@Startup并且其中一个bean恰好是EJB,都是如此。

看看DeltaSpike吧。 有一个CDI控制模块,应该做你现在正在寻找的。 我相信Java EE 7也应该解决这个问题。