118 votes

Quelle est la différence entre les scopes @ApplicationScoped et @Singleton en CDI ?

Dans le CDI, il y a le @ApplicationScoped et le ( javax.inject ) @Singleton pseudo-scope. Quelle est la différence entre eux ? Outre le fait que @ApplicationScoped est procuré, et @Singleton ne l'est pas.

Est-ce que je peux juste changer mon @Singleton haricot à @ApplicationScoped ? Est-ce que @ApplicationScoped bean a deux (ou plus) instances ?

12 votes

Avez-vous lu le Référence de la soudure ? Il y a quelques explications sur les différences pratiques entre @ApplicationScoped et @Singleton à sa section 5.4 (p. 36).

3 votes

A quelle portée de Singleton faites-vous référence - javax.ejb ou javax.inject ?

37voto

Bozho Points 273663

@Singleton ne fait pas partie de la spécification CDI. Il fait partie d'EJB et de javax.inject (JSR-330). Il n'est pas mentionné dans la spécification quel est son comportement, donc vous pouvez seulement vous fier à ce qui est écrit dans la documentation Weld.

15 votes

Ce n'est pas vrai. Il existe une annotation javax.inject.Singleton. Elle fait partie de CDI. Vérifiez ici : docs.jboss.org/weld/reference/1.0.1-Final/fr-US/html_single/

7 votes

@amorphis - J'ai la spécification du CDI sous les yeux. J'en ai même implémenté certaines parties, et elle ne mentionne rien au sujet de l'utilisation de la technologie CDI. @Singleton . Elle n'est présentée que dans un seul exemple, sans précisions. Il est vrai que l'IDC s'appuie sur javax.inject mais, à proprement parler, il ne fait pas partie des spécifications du CDI. Cela dit, j'ai corrigé un peu ma réponse.

21voto

Andreas Dietrich Points 155

en bref : vous pouvez même le mélanger ( @Singleton et @ApplicationScoped ) et cela a du sens dans certains scénarios. (et fonctionne comme prévu dans le mien !)

En plus des autres réponses données jusqu'à présent, j'aimerais ajouter quelques points supplémentaires pour clarifier les scénarios du monde réel.

Pour moi, cette question est née de Comment forcer un bean adapté à une application à s'instancier au démarrage de l'application ? C'est ce que j'ai dit dans une discussion et je n'ai pas trouvé d'argument valable pour le moment :

Dans beaucoup de scénarios et de situations de la vie réelle, je dirais que c'est difficile de dire définitivement - d'un point de vue abstrait/modélisation - si quelque chose est (ou deviendra/serait traité comme) un EJB ou un bean géré au niveau de l'application.

Les arguments (discutables mais non concluants) (de mon point de vue) contre elle jusqu'à présent : (@BalusC et tous les autres : J'aimerais qu'ils soient concluants, mais si ce n'est pas le cas, ce qui précède peut rester vrai et les arguments peuvent néanmoins aider le lecteur à comprendre les différences/avantages/inconvénients/mauvaises/bonnes pratiques).

EJB et Managed Bean

BalusC : C'est un EJB et non un managed bean, ce qui est très différent. Les EJBs fonctionnent en backend et les managed beans en frontend. Les EJBs fonctionnent aussi dans un contexte transactionnel. [...] Vous venez de confondre les beans d'entreprise avec les beans gérés et je viens de le souligner.

mais :

moi : Je pense que vous n'êtes pas tout à fait correct et que vous exagérez le sens/l'usage et cela me semble discutable. http://en.wikipedia.org/wiki/Enterprise_JavaBeans

Enterprise JavaBeans (EJB) est un logiciel géré, côté serveur, pour la construction modulaire de logiciels d'entreprise, et l'une des nombreuses API Java. L'EJB est un composant logiciel côté serveur qui encapsule la logique commerciale d'une application.

Types de haricots d'entreprise

Les Session Beans [3] qui peuvent être soit "Stateful", "Stateless" ou "Singleton" [...]

Les haricots pilotés par messages [...]

... ce qui est toujours vrai dans mon cas.

EJB singleton et Bean à portée applicative

Verrouillage

BalusC : Un EJB singleton n'est pas la même chose qu'un bean à portée applicative. Un EJB singleton est verrouillé en lecture/écriture et donc potentiellement inefficace/survoluté pour la tâche que vous aviez en tête. Pour faire court : prenez un bon livre sur Java EE et apprenez à utiliser le bon outil pour le travail. Un moyen n'est certainement pas l'autre. Le fait que cela fonctionne ne signifie pas que c'est le bon outil. Un marteau de forgeron est capable de fixer une vis, mais ce n'est pas nécessairement le bon outil pour cela :)

mais :

(Je ne vois pas la massue ici - désolé ...) Il est bon de connaître les valeurs par défaut du verrouillage (je n'en avais pas connaissance), mais il semble que ce soit à nouveau incorrect : Oracle Tutoriel Java EE 6 sur Gestion des accès simultanés dans un bean de session singleton

Lors de la création d'un bean de session singleton, l'accès simultané aux méthodes commerciales du singleton peut être contrôlé de deux manières : la concurrence gérée par le conteneur et la concurrence gérée par le bean. [...]

Bien que par défaut, les singletons utilisent une gestion de la concurrence par conteneur, l'annotation @ConcurrencyManagement(CONTAINER) peut être ajoutée au niveau de la classe du singleton pour définir explicitement le type de gestion de la concurrence.

1 votes

Le mélange n'amuse pas Weld : Exception lors du chargement de l'application : Echec de la définition CDI:WELD-000046 : Au plus une portée peut être spécifiée sur [EnhancedAnnotatedTypeImpl] public ApplicationScoped Singleton MyClass. Utilisation de javax.inject.Singleton.

15voto

Grzesiek D. Points 656

Habituellement, lorsque vous voulez avoir une seule instance d'un objet, vous devriez probablement utiliser @ApplicationScoped un tel objet est proxié et peut donc être sérialisé correctement dès le départ.

D'un autre côté, il existe également de nombreux cas où vous ne voulez qu'une seule instance de la classe, mais où cette classe ne peut pas faire l'objet d'une procuration (par exemple parce qu'elle est finale). @Singleton est un sauvetage. Parce que Singleton est un pseudo-scope et ne fait pas l'objet d'une procuration comme tout scope "normal".

1 votes

Je vote contre parce que ce n'est pas très clair. Je code en Java EE depuis cinq ans, je suis des tutoriels et je lis des livres, mais je n'ai aucune idée claire de ce que vous voulez dire quand vous dites "tel objet est proxié", "peut même être correctement sérialisé", et "pseudo-scope". J'aimerais bien savoir ce que vous entendez par là, car il semble que vous sachiez de quoi vous parlez, mais tel qu'il est écrit, je ne peux pas imaginer que votre réponse aidera la plupart des développeurs Java EE.

3 votes

Ceci dit, je sais que les EJBs sont proxiés. Ma confusion porte en partie sur la distinction que vous faites pour les singletons.

9voto

covener Points 3463

@Singleton dans la JSR-299 fait référence aux beans de session singletons ( javax.ejb.Singleton pas javax.inject.Singleton ), et non des beans gérés par la JSR-299 dans une portée intégrée appelée Singleton.

Vous pourriez trouver dans votre serveur que @ApplicationScoped est un par EAR ou un par WAR/EJB-JAR car ce n'est pas clair dans la spécification, mais vous ne devriez certainement pas vous attendre à ce qu'il y en ait un par JVM.

8voto

vigor Points 66

Il y a une autre différence : @Singleton n'est pas un haricot définissant des annotations, comme le fait le système Singleton n'est pas une portée normale. Alors @ApplicationScoped est un haricot définissant des annotations.

Avec la spécification CDI 1.1 : Lorsque l'application est en mode découverte = annoté, Weld n'identifie pas les beans avec @Singleton et pas chargé ce

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