针对Servlet中的上下文查找的EJB注入

时间:2013-11-08 06:49:37

标签: java java-ee servlets ejb

如果我们有statless bean,那么它可以通过@EJB注释注入到Servlet中。例如:

@Stateless
public class LongTimeService {  
    public void do() {
        //logic
    }
}

public class ServletWithBean extends HttpServlet {  
    @EJB
    private LongTimeService bean;

    @Override
    public void service(ServletRequest arg0, ServletResponse arg1)
        throws ServletException, IOException {
             bean.do;
             ...
    }
}

在这种情况下,我们在Servlet的所有生命周期中只有一个LongTimeService bean实例。从ejb容器的角度来看,当web容器用bean构造Servlet时,它会从ejb容器中询问实例并保留这个实例,直到servlet被销毁,每个servlet请求只能用于一个实例。 我认为这是使用Statless EJB的坏方法,因为它不会为这种用法创建。对于这个perpes,例如有用的@Singleton statfull bean。 但是如果我们想要使用无状态bean,那么我们每次都可以在方法内部从Context中查找这个bean的实例。

public class ServletWithBean extends HttpServlet {

    @Override
    public void service(ServletRequest arg0, ServletResponse arg1)
        throws ServletException, IOException {
        Context ctx = new InitialContext();
        LongTimeService bean =  context.lookup("LongTimeService");
             bean.do;
             ...
    }
}

使用这种方法是否正确和可行?

1 个答案:

答案 0 :(得分:4)

  

从web容器构建时的ejb容器角度   使用bean的Servlet从ejb容器中询问实例并保留   这个实例直到servlet将被破坏并且每个servlet请求   只适用于一个实例。

您的推理是正确的,但是,注入到servlet类成员中的实例实际上是一个名为Stub或Proxy的对象的实例,它实际上不是一个EJB实例。

基本上,每次从servlet调用ejb方法时,Stub都会向ejb容器询问对ejb的引用,容器将从池中获取一个可用的ejb,这个ejb将处理请求,一旦工作完成后会回到游泳池。

因此,如果您的servlet同时处理多个请求,则存根将为每个请求获取不同的ejb引用。

请注意,存根对象实现需要是线程安全的(对于Stateless bean来说)。

  

我认为这是使用Statless EJB的不好方法,因为它不会创建   这种用法。

根据以上几点,是的,你可以从servlet中使用@EJB注入。

关于查找存根方法:

它也可以工作(你会得到每个请求一个Stub),但对于无状态是没有必要的,它有一个重要的缺点:查找是一个耗时的操作,因此,你将获得服务的延迟没有补偿的时间反应。

我希望这对你有所帮助。