4

如果我们有 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;
             ...
    }
}

使用这种方法是否正确且可能?

4

1 回答 1

4

从 ejb 容器的角度来看,当 web 容器将使用 bean 构造 Servlet 时,它会从 ejb 容器中请求实例,并将保留此实例,直到 servlet 被销毁并且每个 servlet 请求只能与一个实例一起使用。

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

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

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

请注意,存根对象实现需要是线程安全的(对于无状态 bean 来说也是如此)。

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

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

关于查找存根方法:

它也可以工作(每个请求都会获得一个存根),但对于无状态来说它不是必需的,它有一个重要的缺点:查找是一项耗时的操作,因此,您将在服务时间响应中获得延迟,而无需赔偿。

我希望这对你有帮助。

于 2013-11-10T00:39:46.067 回答