2016-06-10 12 views
0

Ich versuche, ein einfaches Beispiel von @Stateful, @Stateless und @Singleton EJB Beans zu machen, um mir zu helfen, die Unterschiede besser zu verstehen. Das Problem ist, dass es keinen Unterschied gibt, wenn ich die Bean mit einer der @Stateful-, @Stateless- oder @Singleton-Annotationen annotiere. HierGleiches Ergebnis von Stateful, Stateless und Singleton EJB Beans

ist die Bohne:

import javax.ejb.Singleton; 
import javax.ejb.Stateful; 
import javax.ejb.Stateless; 


    @Stateful 
    public class Bean { 
     private int counter = 0; 

     public int getCounter(){ 
      return counter++; 
     } 
    } 

Und hier ist der Servlet-Kunde:

import java.io.IOException; 
import java.io.PrintWriter; 

import javax.ejb.EJB; 
import javax.servlet.ServletException; 
import javax.servlet.annotation.WebServlet; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

import javaeetutorial.converter.ejb.Bean; 

@WebServlet(urlPatterns="/") 
public class Client extends HttpServlet{ 

    @EJB 
    Bean bean; 

    protected void processRequest(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 
     response.setContentType("text/html;charset=UTF-8"); 
     PrintWriter out = response.getWriter(); 
     out.println("<html lang=\"en\">"); 
     out.println("<head>"); 
     out.println("<title>test</title>"); 
     out.println("</head>"); 
     out.println("<body>"); 
     out.println("<h1>Servlet ConverterServlet at " + 
       request.getContextPath() + "</h1>"); 
     try { 
      out.println("<form method=\"get\">"); 
      out.println("<input type=\"submit\" value=\"Submit\">"); 
      out.println("</form>"); 
      out.println("<p>" + bean.getCounter() + "</p>");  
      out.println("<p>" + bean + "</p>"); 
     } finally { 
      out.println("</body>"); 
      out.println("</html>"); 
      out.close(); 
     } 
    } 

    @Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 
     processRequest(request, response); 
    } 

    @Override 
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 
     processRequest(request, response); 
    } 

} 

Die erwarteten Ergebnisse sind für mich:

@Statefull - wenn alle anderen Client drücken Sie die Taste zum Zählen von 0

@Singleton - wenn irgendein Kunde drück e Taste nur eine Zählung

@Stateless zu sehen - ich weiß nicht, was genau

+0

Beschreiben Sie die Tests, die Sie ausführen – fantarama

Antwort

0

Das Problem, das Sie haben, ist, dass die webservlet einmal instanziiert wird (oder zumindest nicht einmal pro Anfrage, das ist, was man deutlich den Unterschied sehen müsste), so ist es die Bean-Instanz. Daher gibt es keinen Unterschied, welche Art von Bean Sie verwenden (Stateful, Stateless, Singleton), da die Bean-Instanz immer von derselben Servlet-Instanz abhängig ist.

Wenn Sie verwenden eine requestScoped Ressource, mit der Singleton Anmerkung würden Sie zählen, wie oft der angeforderte Zähler waren (alle Anfragen die gleiche Instanz teilen), mit dem Stateful würden Sie sehen, wie viele mal hat ein Client den Zähler angefordert, und mit wäre statusless davon abhängig. Da der Zähler jedoch ein Zustand ist, macht es keinen Sinn, eine Statless-Bean zu verwenden (sehen Sie sich den Namen an). Sie können statesless als gepoolt ejb verstehen, so dass jedes Mal, wenn die Bean benötigt wird, der Server eine Instanz des zustandslosen Pools abrufen wird. Ein Vorteil ist die Leistung der Bean, da sie bereits in den Pool (überprüfen Sie die statusfreie Pool-Konfiguration) sind sie wirklich schnell zu verwenden.

Sie können weitere Informationen finden here.

1

Die erwarteten Ergebnisse sind zu erwarten:

  • @Stateful - Stateful Session Beans Timeouts, so dass Sie sollte nie eine Stateful Session-Bean in ein langlebiges Objekt wie ein Servlet injizieren. Stattdessen sollten Sie nur nachschlagen und sie verwenden (möglicherweise durch Einfügen der Referenz in eine HttpSession). Das erwartete Ergebnis ist die Bean-Instanz und ihr Zähler wird von allen Anfragen gemeinsam verwendet. Wenn Sie gleichzeitig Anfragen stellen, blockiert jede einzelne auf den Zugriff auf die Stateful-Session-Bean (versuchen Sie, der getCounter-Methode einen Ruhezustand hinzuzufügen und dann Anforderungen zu stellen aus mehreren Browser-Tabs/Windows). Wenn Sie für einen bestimmten Zeitraum keine Anforderung stellen, wird die Bean entfernt, was dazu führt, dass alle nachfolgenden Anforderungen fehlschlagen. Sie können @StatefulTimeout(value=1, unit=TimeUnit.SECONDS) verwenden, um dies einfach zu beobachten.

  • @Singleton - Die Bean-Instanz und ihr Zähler werden von allen Anfragen gemeinsam genutzt. Standardmäßig verwenden Singletons containergesteuerte Parallelität, sodass in einer Methode jeweils nur eine Anfrage zulässig ist. Auch hier können Sie der getCounter-Methode einen Schlaf hinzufügen, um dies zu beobachten.

  • @Stateless - Abhängig von der Pooling-Konfiguration Ihres Anwendungsservers werden möglicherweise mehrere Bean-Instanzen erstellt, die für gleichzeitige Anforderungen benötigt werden, und Bean-Instanzen können über Anforderungen hinweg wiederverwendet werden. Auch hier können Sie der getCounter-Methode einen Schlaf hinzufügen und Anfragen von mehreren Browser-Tabs/-Fenstern ausführen, um dies zu beobachten. Stateless-Session-Beans sollen dazu verwendet werden, andere EJB-Services zu kapseln (z. B. Transaktionen, Sicherheit, Planung usw.), so dass Membervariablen nur für den Cache-Status verwendet werden sollten, der unabhängig vom Client verwendet werden kann DataSource, UserTransaction usw.), um den Status nicht zu speichern.