【问题标题】:CDI Producer causes stackoverflowCDI Producer 导致 stackoverflow
【发布时间】:2013-03-05 00:09:41
【问题描述】:

我想创建一个生产者来动态选择我的接口 Hello 的实现。

public interface Hello extends Serializable{

     public String sayHello();
}

你好Impls:

public class HelloBanned implements Hello{

    @Override
    public String sayHello() {
        return "Get out!!!";
    }  
}

public class HelloCoolGuy implements Hello{

   @Override
   public String sayHello() {
       return "Welcome";
   }   
}

我的 sessionBean,我想要生产者方法的地方:

public class UsuarioHandler implements Serializable{

    @Inject
    private Usuario usuario;
    @Inject
    @Preferred
    Hello hello;
    @EJB
    UsuarioBeanLocal userEJB;

    public String login(){
        usuario.setId(2L);
        return userEJB.efetuarLogin(usuario);
    }
    @Produces
    @Preferred
    public Hello getHello(@New HelloBanned ban,
                      @New HelloCoolGuy cool){
        if (usuario.isBannedFlag()){
            return ban;
        }
        return cool;
    }
}

此代码结果在 StackOverFlow 上。我找不到是什么原因造成的。

【问题讨论】:

  • 请发布堆栈跟踪

标签: java jsf jakarta-ee cdi


【解决方案1】:

在 CDI 生产者中支持注入。由于您的类UsuarioHandler 既是生产者又是注入目标,因此堆栈溢出是预期的结果。想一想:

  1. UsuarioHandler 实例化为托管 bean 后,需要注入 @Preferred Hello hello
  2. 那么@Preferred Hello hello 的生产者需要实例化,还有你的UsuarioHandler
  3. 但生产者本身也需要注入@Preferred Hello hello 的实例。
  4. 因此实例化了另一个生产者,依此类推。

由于您的 UsuarioHandler 的对应对象是 @Default,因此容器不会代理它,因此每次需要时创建一个新实例,作为生产者或托管 bean。

【讨论】:

    【解决方案2】:

    将您的生产者方法“getHello”设为静态(甚至可以是私有的)并将 Usuario 作为参数传递。

    @Produces
    @Preferred
    private static  Hello getHello(@New HelloBanned ban,
                          @New HelloCoolGuy cool, Usuario usuario){
        if (usuario.isBannedFlag()){
           return ban;
        }
        return cool;
    }
    

    【讨论】:

      【解决方案3】:

      我发现 CDI 在项目中不起作用的最常见问题是缺少 CDI 的 XML bean 描述符。将 beans.xml 添加到您的 META-INF/beans.xml 或 WEB-INF/beans.xml

      描述符可以为空,如下所示:

          <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://java.sun.com/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
      </beans>
      

      要了解有关 beans.xml 文件的更多信息,请参阅此链接:http://www.seamframework.org/Documentation/WhatIsBeansxmlAndWhyDoINeedIt

      如果这不是问题,请粘贴到您的堆栈跟踪中,以便我们查看您遇到的错误是什么。

      【讨论】:

      • 不,CDI 可以正常工作,只是“Hello”生产者注入不起作用,如果我删除该注入,一切正常。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-20
      • 1970-01-01
      • 2020-07-26
      • 1970-01-01
      • 2016-04-18
      • 2015-06-21
      • 1970-01-01
      相关资源
      最近更新 更多