【问题标题】:Ejb returns java.lang.NullPointerExceptionEjb 返回 java.lang.NullPointerException
【发布时间】:2013-11-22 07:37:43
【问题描述】:

我是 cdi 的新手,这是我的第一步。 我在 ejb 模块中有一个 bean:

@Stateless
public class TestBean {
    public String getIt(){
        return "test";
    }
}

我在战争模块中有一个 POJO(我尝试使用 @EJB 和 @Inject - 结果相同)

public class SaveAction  extends Action{
    @EJB    
    private TestBean bean;

    @Override
    public void execute(){
    ....    
    String test = bean.getIt(); //HERE I GET java.lang.NullPointerException
    ...
    }
}

war 和 ejb 都在耳边。在日志中我看到了

EJB5181:EJB TestBean 的可移植 JNDI 名称: [java:global/example.com/my-ejb/TestBean!com.example.TestBean, java:global/example.com/my-ejb/TestBean]]]

由此我得出结论,bean 已初始化 - 但我找不到它。我做错了什么?

【问题讨论】:

  • SaveAction 在哪里实例化/谁实例化它?
  • @isnot2bad 在 servlet 中实例化。
  • 所以你是通过'new'来做的?
  • @PashaTurok,可能您尝试在 Struts 上注入 EJB bean,请在 HTTPServlet 上尝试。
  • @PashaTurok 当你用'new'自己创建bean时,不会发生神奇的注入!让 CDI 容器创建你的 bean,然后它就可以工作了!

标签: java jakarta-ee glassfish ejb


【解决方案1】:

CDI 和其他依赖注入容器不使用魔法!它只是普通的 java 代码,不能比任何其他地方编写的 java 代码做更多或更少的事情。所以直接通过new实例化对象时,框架是不可能进行注入的:

SaveAction action = new SaveAction();
// don't expect any injection has happened - it can't! no magic!
// action.bean is still null here!

框架不知道像 SaveAction 这样的对象已被实例化。 (因此有必要以某种方式通知框架关于新创建的对象 - 但构造函数和“新”语句都没有这样做!想想你将如何编写这样的框架代码!这是不可能的!*) .

要使注入工作,对象必须由容器创建!否则无法管理! (另见Web Beans specification (JSR 299) 的第 3.7 章)。

最好的方法是让容器将对象注入到另一个已经托管的 bean 中。看起来这只是推迟了问题,但是您的应用程序中已经有一些托管的 bean,例如 servlet!

建议:让您的 SaveAction CDI 感知(例如,使用 @Default 对其进行注释)并将其注入您的 servlet!

教程:


*) 理论上,应该可以使用面向方面的编程或工具来操作 bean 的构造函数,以便在调用它们时通知容器。但这是一个非常复杂的概念,我认为有许多未解决的问题。

【讨论】:

  • 他现在会相信你吗?
  • @isnot2bad 非常感谢!
  • @isnot2bad 你知道,你的答案最重要的部分是“CDI 和其他依赖注入容器不使用魔法!”因为当你开始思考它是如何工作的时候,一切都会变得清晰。
  • @PashaTurok 这就是为什么它在第一行! ;)
猜你喜欢
  • 2017-08-07
  • 1970-01-01
  • 2013-02-12
  • 1970-01-01
  • 1970-01-01
  • 2019-10-07
  • 2023-03-03
  • 2013-12-16
  • 1970-01-01
相关资源
最近更新 更多