Domanda

Ho intenzione attraverso il Java EE 6 tutorial e sto cercando di capire la differenza tra i bean di sessione senza stato e con stato. Se i bean di sessione senza stato non mantengono il loro stato tra chiamate di metodo, perché è il mio programma che agisce così com'è?

package mybeans;

import javax.ejb.LocalBean;
import javax.ejb.Stateless;

@LocalBean
@Stateless
public class MyBean {

    private int number = 0;

    public int getNumber() {
        return number;
    }

    public void increment() {
        this.number++;
    }
}

Il client

import java.io.IOException;
import javax.ejb.EJB;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.WebServlet;
import mybeans.MyBean;
import java.io.PrintWriter;

@WebServlet(name = "ServletClient", urlPatterns = { "/ServletClient" })
public class ServletClient extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @EJB
    MyBean mybean;

    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

        PrintWriter out = response.getWriter();
        mybean.increment();
        out.println(mybean.getNumber());
    }

}

Mi aspettavo di tornare ControllaNumero 0 ogni volta, ma sta tornando 1 e ricarica della servlet nel mio browser aumentare di più. Il problema è con la mia comprensione di come apolidi lavoro bean di sessione e non con le librerie o application server, naturalmente. Qualcuno può darmi un semplice ciao tipo mondo esempio di un bean di sessione senza che si comporta in modo diverso quando si cambia di stateful?

È stato utile?

Soluzione

La differenza importante non è variabili membro private, ma associando stato con un particolare utente (si pensi "carrello della spesa").

Il pezzo stateful di session bean stateful è come la sessione in servlet. Bean di sessione stateful permettere la vostra applicazione di avere ancora quella sessione, anche se non c'è un client web. Quando il server applicazione recupera una sessione bean senza stato fuori dalla piscina oggetto, sa che può essere utilizzato per soddisfare qualsiasi richiesta, perché non è associata a un particolare utente.

Una session bean stateful deve essere doled per l'utente che ha ottenuto in primo luogo, perché la loro spesa informazioni della spesa dovrebbe essere noto solo a loro. L'application server garantisce che sia così. Immaginate quanto sia popolare la vostra applicazione sarebbe se si potesse iniziare lo shopping e poi l'assistente di app ha dato la tua session bean stateful per me quando sono arrivato io!

Così il vostro membro dati privato è infatti "stato", ma non è "carrello della spesa". Provate a rifare la vostra (molto buono) esempio per fare in modo variabile incrementato è associato a un particolare utente. Incrementarlo, creare un nuovo utente, e vedere se possono ancora vedere il valore incrementato. Se fatto correttamente, ogni utente dovrebbe vedere solo la loro versione del contatore.

Altri suggerimenti

chicchi Stateless Session (SLSB) sono non legato per un cliente e non v'è alcuna garanzia per un cliente per ottenere la stessa istanza con ogni metodo invocazione (alcuni contenitori possono creare e distruggere fagioli con ogni sessione di invocazione metodo, si tratta di una decisione specifica attuazione, ma i casi sono in genere pool - e non mi parlare di ambienti cluster). In altre parole, anche se i fagioli apolidi possono avere variabili di istanza, questi campi non sono specifiche di un cliente, in modo da non si basano su di essi tra chiamate remote.

Al contrario, bean di sessione stateful (SFSB) sono dedicato per un cliente per tutta la vita, non c'è scambio o messa in comune di istanze (potrebbe essere sfrattati dalla memoria dopo passivazione per risparmiare risorse, ma questa è un'altra storia) e mantenere lo stato della conversazione . Ciò significa che le variabili del fagiolo istanza possono conservare i dati relativi al client tra le chiamate di metodi. E questo rende possibile avere chiamate di metodo interdipendenti (modifiche apportate da un metodo influenzano le chiamate di metodo successive). processi multi-step (un processo di registrazione, un carrello della spesa, un processo di prenotazione ...) sono casi d'uso tipici per SFSB.

Ancora una cosa. Se si utilizza SFSB, allora si deve evitare iniettando loro in classi che sono multithreaded in natura, come Servlet e JSF riuscirono fagioli (non si vuole che sia condiviso da tutti i client). Se si desidera utilizzare SFSB nella propria applicazione web, allora avete bisogno di eseguire una ricerca JNDI e memorizzare l'istanza EJB restituita nell'oggetto HttpSession per l'attività futura. Qualcosa del genere:

try {
    InitialContext ctx = new InitialContext();
    myStateful = (MyStateful)ctx.lookup("java:comp/env/MyStatefulBean");
    session.setAttribute("my_stateful", myStateful);
} catch (Exception e) {
    // exception handling
}

Stateless e stateful, in questo contesto non significa proprio quello che ci si potrebbe aspettare.

statefulness con EJB si riferisce a quello che io chiamo lo stato della conversazione . L'esempio classico è una prenotazione di volo. Se si compone di tre fasi:

  • Sedile Reserve
  • ricarica carta di credito
  • emissione del biglietto

Immaginate ognuno di questi è un metodo chiamata a un session bean. Una session bean stateful in grado di mantenere questo tipo di conversazione in modo che ricorda quello che accade tra le chiamate.

I bean di sessione senza stato non hanno tale capacità di stato della conversazione.

Le variabili globali all'interno di una session bean (stateful senza stato o) sono qualcosa di completamente diverso. Bean di sessione stateful avranno un pool di fagioli creato (in quanto un fagiolo può essere utilizzato solo in una conversazione alla volta), mentre i fagioli Sesion apolidi spesso hanno una sola istanza, che renderà le opere variabili globali, ma non credo questo è necessariamente garantita.

Questa cosa accadere perché il contenitore ha una sola istanza di bean nel pool che viene riutilizzata per tutte le chiamate. Se si esegue i client in parallelo si vedrà un risultato diverso perché il contenitore creerà più istanze di fagioli in piscina.

Ha buone risposte. Vorrei aggiungere piccole risposta. Stateless Bean non dovrebbe utilizzato per contenere tutti i dati dei clienti. Dovrebbe essere usato per "modellare azioni o processi che possono essere fatte in un solo colpo".

Le principali differenze tra i due principali tipi di fagioli di sessione sono:

fagioli apolidi

  1. Fagioli Stateless Session sono quelli che non hanno lo stato della conversazione con il cliente che ha chiamato i suoi metodi. Per questo motivo si può creare un pool di oggetti che possono essere utilizzati per interagire con più client.
  2. Prestazioni saggio fagioli apolidi sono migliori in quanto non hanno stati per cliente.
  3. Si può gestire più richieste da più client in parallelo.

fagioli stateful

  1. Bean di sessione stateful possono mantenere lo stato della conversazione con più client alla volta e il compito non è condivisa tra i client.
  2. Dopo la sessione è stata completata lo stato non viene mantenuto.
  3. Il contenitore può serializzare e memorizzare lo stato come un Stato di stantio per un utilizzo futuro. Questo viene fatto per salvare le risorse del server applicazioni e per sostenere i guasti di fagioli.

Buona domanda,

provare questo codice (cambiamento MyBean Stateful / Stateless.):

import javax.ejb.LocalBean;
import javax.ejb.Stateful;
import javax.ejb.Stateless;

@LocalBean 
@Stateless 
public class MyBean {

    private int number = 0;

    public int getNumber() {
        return number;
    }

    public void increment() {
        this.number++;
    }
}

Servlet_1

 import java.io.IOException;
    import javax.ejb.EJB;
    import javax.servlet.*;
    import javax.servlet.http.*;
    import javax.servlet.annotation.WebServlet;

    import java.io.PrintWriter;

    @WebServlet(name = "ServletClient", urlPatterns = { "/ServletClient" })
    public class ServletClient extends HttpServlet {

        private static final long serialVersionUID = 1L;

        @EJB
        MyBean mybean;

        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

            PrintWriter out = response.getWriter();
            mybean.increment();
            out.println(mybean.getNumber());
        }

    }

Servlet_2

import java.io.IOException;
import javax.ejb.EJB;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.WebServlet;

import java.io.PrintWriter;

@WebServlet(name = "NewServletClient", urlPatterns = { "/NewServletClient" })
public class NewServletClient extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @EJB
    MyBean mybean;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        PrintWriter out = response.getWriter();
        mybean.increment();
        out.println(mybean.getNumber());
    }

}

caso: MyBean - @ Stateless

http: // localhost: 8080 / MYServletDemo / ServletClient

1

http: // localhost: 8080 / MYServletDemo / ServletClient

2

http: // localhost: 8080 / MYServletDemo_war_exploded / newServletClient

3

http: // localhost: 8080 / MYServletDemo / ServletClient

4

caso: MyBean - @ Stateful

http: // localhost: 8080 / MYServletDemo / ServletClient

1

http: // localhost: 8080 / MYServletDemo / ServletClient

2

http: // localhost: 8080 / MYServletDemo / newServletClient

1

http: // localhost: 8080 / MYServletDemo / ServletClient

3

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top