J2EE : Singletons
Développer soit-même un singleton, cela n’a plus aucun intérêt. Des annotations sont faites pour cela :
@javax.ejb.Singleton
– Un nouveau type d’EJB provenant dans la JSR-318. Il est utilisé pour obtenir une seule instance partagée d’une même EJB. Cette instance est thread safe et transactionnelle.@javax.inject.Singleton
– Provient de la JSR-330, la classe annotée de cette manière ne sera instanciée qu’une seule fois.@javax.enterprise.inject.ApplicationScoped
– Un scope provenant de la JSR-299 (CDI), le bean est dans le scope application.@javax.faces.bean.ApplicationScoped
– Définie dans JSF 2.0 (JSR-314) Managed Beans, c’est un managed bean JSF qui est placé dans le scope application.
Toutes ces annotations vont nous permettre d’obtenir des singletons. Mais quelles sont les différences entre elles ?
La différence entre les deux annotations @javax.enterprise.inject.ApplicationScoped
et @javax.faces.bean.ApplicationScoped
c’est le contexte de déploiement. Si le conteneur utilisé est compatible CDI il faut utiliser l’annotation CDI sinon, si le conteneur n’est pas compatible CDI (par exemple Tomcat) il faut utiliser l’annotation JSF2.0.
Quelles sont donc les différences entre les trois premières annotations ?
L’annotation EJB - @javax.ejb.Singleton
– est la seule à proposer les services “entreprise”, c’est à dire la gestion des transactions et de la concurrence. Il faut donc l’utiliser quand ces services “entreprise” sont nécessaires. Remarque, dans ce cas, il est tout à fait possible d’utiliser un EJB statefull avec un scope application - @javax.enterprise.inject.ApplicationScoped
. Cet objet sera gérer de façon différente par le conteneur CDI mais il aura exactement les mêmes caractéristiques qu’un EJB @javax.ejb.Singleton
. Donc, à mon avis, autant utiliser l’EJB singleton plutôt que le statefull en scope application.
Si vous n’avez pas besoin des services “entreprise”, autant utiliser un POJO normal, managed bean dans J2EE, avec le scope application. C’est à dire @javax.enterprise.inject.ApplicationScoped
.
L’annotation @javax.inject.Singleton
ne sera vraiment utile que dans un contexte J2SE. Pour plus d’information, il faut lire la documentation de référence de weld concernat le pseudo-scope Singleton.
Bonjour,
Votre article est très intéressant.
J’ai essayé de voir fonctionner correctement l’exemple “numberguess” du fameux “quickstart-master”, sur Wildfly.
De là, j’ai pu constater que l’option @ApplicationScoped ne fonctionne pas correctement. Càd un nombre est généré à chaque connexion client.
Comme indiqué ci-après, un nombre est généré à chaque connexion client (postes différents) :
11:33:05,285 INFO [stdout] (default task-33) Number is 55
11:33:38,487 INFO [stdout] (default task-34) Number is 27
11:33:48,483 INFO [stdout] (default task-36) Number is 67
11:33:58,904 INFO [stdout] (default task-37) Number is 5
Je pensais qu’un seul nombre est partagé par toutes connexions client. Mais ce n’est pas le cas. Sauriez-vous me dire pourquoi?
D’avance merci.
Bonjour,
Dans l’exemple numberguess (https://github.com/sgilda/wildfly-quickstart/tree/master/numberguess) le “Number” est regénéré à chaque appel. C’est à dire que la méthode “int next()” de la classe “Generator” est appelée à chaque injection de “@Inject @Random Instance randomNumber;”.
Par contre la classe Generator qui est annotée avec @ApplicationScoped ne sera instanciée qu’une seule et unique fois dans l’application.