6

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

我们同时使用EJB 3.1和,因为它们由不同的容器控制,我们可以通过使用和注释CDI 1.0来控制 EJB 托管 Bean 何时以及以何种顺序启动。@Startup@Singleton

但是@Inject我在课堂上声明的 CDI bean 将变为 null,因为 CDI 容器尚未启动。

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

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

拜托,如果你能帮我找到一种方法来控制内部的 CDI 上传,而不管 EJB 是什么?

这是它的示例代码:

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

3 回答 3

5

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

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

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

有用!!

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

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

于 2013-01-14T15:07:38.797 回答
3

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

@Singleton
@Startup
public class BaseStartupLoader {

    @Inject @MyStartup
    BaseStartUp myStartup;

    @Inject
    private InjectionTest test;


    public static class InjectionTest {}
}

如果test变量在 中出现 null @PostConstruct,则 CDI 可能未在声明的 jar 中启用BaseStartupLoader

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

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

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

于 2012-12-25T00:11:11.663 回答
0

看看 DeltaSpike。有一个 CDI 控制模块应该可以满足您的需求。我相信 Java EE 7 也应该解决这个问题。

于 2012-12-25T19:41:27.017 回答