98 votes

Beans Enterprise Java sans état et avec état

Je vais dans Java EE 6 tutoriel et je suis en train d'essayer de comprendre la différence entre stateless et stateful session beans. Si beans de session sans état ne conservent pas leur état entre les appels de méthode, pourquoi mon programme est en agissant de cette manière?

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++;
    }
}

Le 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());
    }

}

Je m'attendais à getNumber pour revenir à 0 à chaque fois mais il est de retour 1 et recharge de la servlet dans mon navigateur l'augmenter davantage. Le problème, c'est avec ma compréhension de la façon dont stateless beans de session de travail et non pas avec les bibliothèques ou de serveur d'applications, bien sûr. Quelqu'un peut-il me donner un simple hello world exemple type d'un bean session sans état qui se comporte différemment lorsque vous la changez pour stateful?

138voto

Pascal Thivent Points 295221

Beans de Session sans état (SLSB) sont pas liés à un client et il n'y a pas de garantie pour un client d'obtenir la même instance à chaque invocation de méthode (certains conteneurs peuvent créer et de détruire des haricots à chaque invocation de méthode de session, c'est une mise en œuvre spécifique de la décision, mais des cas sont généralement mis en commun et je ne mentionne pas les environnements de clusters). En d'autres termes, bien que les haricots apatrides peuvent avoir des variables d'instance, ces champs ne sont pas spécifiques à un client, de sorte ne comptez pas sur eux entre les appels distants.

En revanche, Stateful Session Beans (SFSB) sont dédiés à un client pour toute leur vie, il n'y a aucun échange ou la mise en commun des instances (il peut être expulsé de la mémoire après passivation pour économiser des ressources, mais c'est une autre histoire) et de maintenir l'état conversationnel. Cela signifie que les variables d'instance de la fève peut conserver les données relatives au client entre les invocations de méthode. Et cela permet d'avoir interdépendants les appels de méthode (les modifications apportées par une méthode affecte pas les appels de méthode). Multi-étape de processus (processus d'enregistrement, un panier, un processus de réservation,...) sont des cas d'utilisation typique pour SFSB.

Une chose de plus. Si vous utilisez SFSB, alors vous devez éviter de les injecter dans des classes qui sont multithread dans la nature, comme les Servlets et JSF géré haricots (vous ne voulez pas qu'il soit partagé par tous les clients). Si vous souhaitez utiliser SFSB dans votre application web, vous devez effectuer une recherche JNDI et de stocker le retour de l'EJB instance dans l' HttpSession l'objet d'une activité future. Quelque chose comme ça:

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

97voto

duffymo Points 188155

La différence importante n'est pas membre privé variables, mais d'associer l'etat à un utilisateur particulier (penser "panier").

Une pièce de stateful session bean est comme la session dans les servlets. Stateful session beans permettre à votre application de toujours avoir cette session, même si il n'y a pas un client web. Lorsque le serveur d'application récupère un bean session sans état de l'objet de la piscine, il sait qu'il peut être utilisé pour satisfaire TOUTE demande, car il n'est pas associé à un utilisateur particulier.

Un stateful session bean a être distribués à l'utilisateur qui a eu en premier lieu, en raison de leur panier d'info doit être les seuls à connaître. Le serveur d'application assure que c'est le cas. Imaginer la popularité de votre application serait si vous pouviez commencer à magasiner, puis le serveur d'application a donné votre stateful session bean pour moi quand je suis venu le long!

Afin que vos données privées des membres est en effet un "état", mais ce n'est pas "panier". Essayer de refaire votre (très bon) exemple de faire en sorte que le incrémenté variable est associée à un utilisateur particulier. L'incrémenter, créez un nouvel utilisateur, et de voir si ils peuvent encore voir la valeur incrémentée. Si fait correctement, chaque utilisateur devrait voir juste leur version de la contre.

18voto

cletus Points 276888

Stateless et stateful dans ce contexte ne signifie pas du tout ce à quoi vous pourriez vous attendre.

Statefulness avec les Ejb se réfère à ce que j'appelle l' état conversationnel. L'exemple classique est celui d'une réservation de vol. Si il se compose de trois étapes:

  • Réserve de siège
  • Frais de carte de crédit
  • Le Ticket

Imaginez que chacun de ces est un appel de méthode d'un bean session. Un stateful session bean peut maintenir ce genre de conversation de sorte qu'il se souvient de ce qui se passe entre les appels.

Beans de session sans état n'ont pas la capacité pour l'état conversationnel.

Les variables globales à l'intérieur d'un session bean (apatrides ou stateful) sont quelque chose d'autre entièrement. Stateful session beans sera un pool de haricots créé (depuis un bean ne peut être utilisé dans une conversation à la fois) alors que stateless session beans souvent seulement avoir une instance qui fera la variable globale fonctionne, mais je ne pense pas que ce soit nécessairement garanti.

4voto

Neyma Points 23

Cela se produit parce que le conteneur n'a qu'une seule instance de bean dans le pool qui est réutilisée pour tous les appels. Si vous exécutez les clients en parallèle, vous obtiendrez un résultat différent car le conteneur créera plus d'instances de beans dans le pool.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X