【问题标题】:Using EJB injection in a POJO在 POJO 中使用 EJB 注入
【发布时间】:2012-10-26 08:08:59
【问题描述】:

我知道使用@EJB 注解的注入只能在 EJB 类、servlet 或 JSF 托管 bean 中使用,但同时我需要在 POJO 类中拥有某个注入业务接口的实例,所以我想到了以下操作:

在我的 JSF 托管 bean 中

@EJB BusinessInterfaceLocal businessInterface;

private void someMethod(){
    PojoInterface pojo = new PojoClass(this.businessInterface);
}

在我的 POJO 类中我有这个构造函数

BusinessInterfaceLocal businessInterface;    

public PojoClass(BusinessInterfaceLocal businessInterface){
   this.businessInterface = businessInterface;

   //The following throws a Null Pointer Exception
   this.businessInterface.someMethodCall();
}

上述方法不应该正常工作吗?但事实并非如此,PojoClass 中的 businessInterface 对象被评估为 null,从而引发空指针异常。

我希望有人能指出我做错了什么。

提前致谢。

【问题讨论】:

  • 要使注入正常工作,您需要使用 @Stateless 之类的东西声明类,以便注入可以发生。您能提供整个课程以便我们查看吗?
  • 问题不在于业务接口,因为我可以在其他地方使用它,并且确实使用Stateless注解进行了注解,并且它实现的接口使用Local进行了注解,但是当我使用时错误上升尝试在普通类中在托管 bean 之外使用它
  • NullPointerException 抛出的究竟在哪里?是在你说的那一行,还是在堆栈的更深处?
  • 就在我说的那一行,我调试了它,结果 this.businessInterface 被评估为 null
  • POJO 中的注入只有在 POJO 是容器管理的情况下才有效!这意味着它必须是例如通过@Inject 实例化!使用 new() 的实例化不是容器管理的。

标签: java jsf jakarta-ee ejb pojo


【解决方案1】:

问题是由于我试图在构造函数中使用 businessInterface 对象引起的,而容器仅在完成托管 bean 的实例化后才注入 ejb,

参考类似问题https://stackoverflow.com/a/6537228/1249304

我所做的是我创建了一个方法并使用 @PostConstruct 注释对其进行注释,这样在容器完成托管 bean 的实例化之后,将调用带注释的方法并且 businessInterface 对象不再为空

@PostContsruct
public void onInit(){
   //businessInterface is no longer null
   businessInterface.someMethod();
}

【讨论】:

    【解决方案2】:

    验证

    是否可以在注入 EJB 之前创建 PojoClass。我的意思是,你在哪里调用“someMethod”?它在托管bean的构造函数中吗?变量不会丢失其引用值。

    您说您可以看到托管 bean 中的 BusinessInterfaceLocalbean 不为空,您能否在检查后验证您创建了 Pojo?

    替代解决方案:

    解决方案 1 您可以将 POJO 用作无状态 bean,我认为这样做没有任何问题,当然,除非您尝试在 EE 容器之外使用 POJO,也就是说,看起来并非如此。

    使 POJO 无状态将使您能够注入 EJB。

    解决方案 2 或 JNDI 查找,实现如下:

    @Stateless(name="myEJB")
    public class MyEJB {
    
      public void ejbMethod() {
      // business logic
      }
    
    }
    
    public class TestEJB {
    
      public static void main() {
      MyEJB ejbRef = (MyEJB) new InitialContext().lookup("java:comp/env/myEJB");
      ejbRef.ejbMethod();
      }
    }
    

    【讨论】:

      【解决方案3】:

      使用上面显示的代码,NullPointerException 可以在指示的行被抛出的唯一方法是托管 bean 中的 businessInterface 字段为空。当从一个对象传递到另一个对象时,引用不会神秘地变为空,PojoClass 不会做任何会导致变量变为空的事情。我建议您进行一些调试或日志记录,以确定在调用构造函数时托管 bean 中字段的值。如果它为空,那么问题在于注入到 bean 中,与 POJO 无关,您应该修复它。

      如果抛出的异常实际上比您显示的行更深,那么这可能是在错误的上下文中使用 EJB 代理的问题。您可能知道,对 EJB 的引用通常不是对 EJB 本身的引用,而是对某种将方法调用传递给 EJB 的代理。代理存在,因此容器可以介入并执行诸如启动事务、检查授权等操作。代理可能需要调用某些上下文资源来完成其工作,这些资源在从托管 bean 访问 EJB 时可用,但由于某些不明显和扭曲的原因,从 POJO 访问时不可用。这些资源的不可用可能导致NullPointerException。现在,我认为简单地将托管 bean 的引用传递给 POJO 不太可能让您陷入这种情况;仅当您执行诸如从不同线程访问托管 bean 之类的操作时才会发生这种情况。所以,应该不是这个吧!

      【讨论】:

      • 使用您显示的代码,这不可能发生。检查你的假设。
      • 如果你允许我进一步调查这个问题,我会尽快回复你,但我很确定你说的是最合理的
      • 确实是注入问题,我不能在托管bean中使用@EJB注入对象
      猜你喜欢
      • 1970-01-01
      • 2012-09-07
      • 1970-01-01
      • 2011-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-15
      • 1970-01-01
      相关资源
      最近更新 更多