如果我们有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;
...
}
}
使用这种方法是否正确和可行?
答案 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),但对于无状态是没有必要的,它有一个重要的缺点:查找是一个耗时的操作,因此,你将获得服务的延迟没有补偿的时间反应。
我希望这对你有所帮助。