¿Por qué los beans Stateful y Stateless se comportan de manera opuesta?

Creé clases Stateful, Stateless y Singleton Bean e bash acceder a dos servlets diferentes. Y ejecutar el proyecto en el servidor de JBoss.

Cuando tengo acceso a Stateful Bean desde cada servlet, se crearán dos objetos bean diferentes y se conservarán diferentes estados (datos) para ellos. Pero el objeto bean sin estado se comparte entre ambos servlets. El frijol Singleton también se comporta de la misma manera que el frijol sin estado.

Mi pregunta es ¿por qué bean stateful y stateless se comporta de manera opuesta? ¿El ciclo de vida del bean de sesión es el mismo que el ciclo de vida del servlet?

FirstServlet.java

@WebServlet("/FirstServlet") public class FirstServlet extends HttpServlet { private static final long serialVersionUID = 1L; @EJB StatelessBean statelessBean; @EJB StateFullBean statefulBean; @EJB SingletonBean singletonBean; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String message = "Beans not injected."; String beanType = request.getParameter("beanType"); if ("Stateless".equals(beanType)) { if (statelessBean != null) { message = statelessBean.getHits(); } else { message = "Stateless bean not injected."; } } if ("Stateful".equals(beanType)) { if (statefulBean != null) { message = statefulBean.getHits(); } else { message = "Stateful bean not injected."; } } if ("Singleton".equals(beanType)) { if (singletonBean != null) { message = singletonBean.getHits(); } else { message = "Singleton bean not injected."; } } response.setContentType("text/html"); response.getWriter().print("

" + message + "

"); } }

Del mismo modo, creé un servlet más DemoServlet.java.

StateFullBean.java

 @Stateful public class StateFullBean{ int hits=0; public String getHits() { hits++; return "StateFullBean number of hits " + hits; } public StateFullBean() { System.out.println("StateFullBean created."); } } 

StatelessBean.java

 @Stateless public class StatelessBean{ int hits=0; public String getHits() { hits++; return "StatelessBean number of hits " + hits; } public StatelessBean() { System.out.println("StatelessBean created."); } } 

SingletonBean.java

 @Startup @Singleton(name="SingletonBean") public class SingletonBean { int hits=0; public SingletonBean() { System.out.println("SingletonBean created."); } public String getHits() { hits++; return "Singleton bean number of hits " + hits; } } 

¿Me perdí algo en el código?

Todo se comporta como se especifica.

Un EJB sin estado delega la llamada más a la instancia disponible actualmente en el grupo. Aparentemente solo hay uno que no se usa al mismo tiempo (todavía) y, por lo tanto, todos los clientes tienen las mismas posibilidades de acceder a la misma instancia en el grupo. Si activa más solicitudes HTTP al mismo tiempo en los servlets, entonces aumentan las posibilidades de que ya no haya ninguna instancia disponible y el contenedor creará una nueva instancia en el grupo.

Un EJB con estado está vinculado a su cliente (en su caso, la instancia del servlet web). En otras palabras, cada servlet tiene su propia instancia de EJB con estado que no se comparte en ninguna otra parte.

Un bean singleton es amplio y se comparte entre todos los clientes. En otras palabras, cada servlet compartirá la misma instancia EJB única.

Tenga en cuenta que los términos “cliente” y “sesión” en el contexto EJB no son en absoluto los mismos que en el contexto WAR y aquí es donde muchos principiantes se caen. El cliente EJB no es el navegador web, sino la instancia de la clase donde se inyecta el EJB (en su caso, la instancia del servlet web). La sesión EJB no es la sesión HTTP, sino la sesión EJB-cliente.

Ver también:

  • @Inject stateless EJB contiene datos de solicitudes anteriores
  • ¿Por qué los beans de sesión sin estado?
  • Cuando se usa @EJB, ¿cada bean administrado obtiene su propia instancia de @EJB?