我是这里的新手,也是CDI世界的新手,我在工作中的第一项任务是找到一种控制CDI上传的方法。
我们正在使用EJB 3.1
和CDI 1.0
,并且因为它们由不同的容器控制,我们可以使用@Startup
控制EJB Managed Beans的启动时间和顺序和@Singleton
注释。
但是我在我的类中声明的@Inject
CDI bean因为CDI Container尚未启动而变为null。
我现在已经尝试了几天寻找解决方案,而我发现here没有效果的解决方案(仍然是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();
}
}
答案 0 :(得分:5)
经过大量研究后,我从IBM的人那里得到了一些帮助,因为我们正在使用WebSphere Application Server,我只需添加一个名为的JVM属性:
“com.ibm.ws.cdi.immediate.ejb.start”= true
到管理控制台中的WAS,他将确保一旦我在@Startup bean中获得EJB @PostConstruct方法,我创建的CDI容器就已经启动并且已经注入。
有效!!
以下是IBM站点中问题和解决方案的链接:
答案 1 :(得分:3)
也许仔细检查CDI实际上是否在应用程序所需的所有位置启用。尝试将此代码添加到BaseStartupLoader
作为实验:
@Singleton
@Startup
public class BaseStartupLoader {
@Inject @MyStartup
BaseStartUp myStartup;
@Inject
private InjectionTest test;
public static class InjectionTest {}
}
如果test
中的@PostConstruct
变量为null,则可能未在声明BaseStartupLoader
的jar中启用CDI。
例如,如果说,BaseStartupLoader
在名为orange.jar
的jar中声明,MyStartUpLoader
在名为yellow.jar
的jar中声明,则这两个文件必须存在:
orange.jar!/META-INF/beans.xml
yellow.jar!/META-INF/beans.xml
如果通过META-INF/beans.xml
在两个罐子中正确启用CDI,那么这是容器中的错误。在@Inject
被调用之前,需要完成所有@PostConstruct
点(对于启用CDI的jar)。无论是否使用@Startup
且其中一个bean恰好是EJB,都是如此。
答案 2 :(得分:0)
看看DeltaSpike。有一个CDI控制模块,应该做你现在正在寻找的。我相信Java EE 7也应该解决这个问题。