cdi - javax.enterprise.context.ContextNotActiveException 在@Producer 方法中使用作用域 bean

cdi - javax.enterprise.context.ContextNotActiveException while using scoped beans in @Producer methods

我正在使用 Websphere Application Server 8.0.0.5,我在使用 CDI 时发现了以下问题。

  1. Classes which have @Producer methods cannot have any scope other than @Dependent
  2. Any bean whose scope is other than @Dependent cannot be injected and used in classes with @Producer methods.

在执行上述任何任务时,我得到:

[10/8/15 14:50:30:764 GMT+05:30] 00000019 InjectInjecti E   CWOWB0102E: A JCDI error has occurred: WebBeans context with scope type annotation @ApplicationScoped does not exist within current thread
[10/8/15 14:50:30:766 GMT+05:30] 00000019 BusinessExcep E   CNTR0019E: EJB threw an unexpected (non-declared) exception during invocation of method "doSomething". Exception data: javax.ejb.EJBException: Injection failure; nested exception is: javax.enterprise.context.ContextNotActiveException: WebBeans context with scope type annotation @ApplicationScoped does not exist within current thread
javax.enterprise.context.ContextNotActiveException: WebBeans context with scope type annotation @ApplicationScoped does not exist within current thread
        at org.apache.webbeans.container.BeanManagerImpl.getContext(BeanManagerImpl.java:321)
        at org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.getContextualInstance(NormalScopedBeanInterceptorHandler.java:124)
        at org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.invoke(NormalScopedBeanInterceptorHandler.java:95)

......

复制问题的示例代码:

public class Producer{

    @Inject
    @MyQualifier
    private Properties properties;

    @Produces
    public Logger getLogger(InjectionPoint ip){
        System.out.println(properties);
        System.out.println("Injection point is: "+ip);
        return Logger.getLogger(ip.getMember().getDeclaringClass().getName());
    }


}





public class AnotherProducer{

    @Produces
    @MyQualifier
    @ApplicationScoped
    public Properties getProperties(){

        Popperties p = new Properties();
        p.put("key","value");

        return p;
    }   
}

我的问题是 - 我是否违反了 CDI 规范或我的容器有问题?

根据 CDI 规范,类型 @ApplicationScoped 的范围应该始终可用 - 通常这意味着此范围内的对象在您的应用程序的生命周期内存在。

但您似乎遇到了 Websphere 中的错误,如 here 中所述。如果你想使用 @ApplicationScoped 个 bean,你有以下选项:

  • 切换到不同的应用程序服务器或升级 Websphere,或者至少升级 WebSphere 中的 WebBeans 库(也许 不是你的选择)
  • 创建一个 CDI 扩展以添加您的自定义 @ApplicationScoped 范围(可能对某些内容编码过多,应用服务器应该已经支持)
  • 不要在您的生产者上使用 @ApplicationScoped,而是将创建的 bean 缓存在 Singleton bean 中(如果它们是之前创建的)