web-dev-qa-db-fra.com

Quelle est la différence entre les étendues @ApplicationScoped et @Singleton dans CDI?

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

Puis-je simplement changer mon @Singleton bean vers @ApplicationScoped? Pouvez @ApplicationScoped bean a deux (ou plus) instances?

83
amorfis

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

24
Bozho

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 à ce jour, j'aimerais ajouter quelques points de clarification dans les scénarios du monde réel.

Pour moi, cette question a été développée à partir de Comment puis-je forcer un bean à portée d'application à instancier au démarrage de l'application? Dans une discussion, j'ai déclaré cela et je ne trouve pas d'argument valable à ce jour:

Dans de nombreux scénarios/configurations réels, je dirais qu'il est difficile de dire avec certitude - d'un point de vue abstrait/modélisation - si quelque chose est (ou deviendra/sera traité comme) un EJB ou bean géré à portée d'application.

(discutable mais pas concluant) des arguments (de mon point de vue) contre cela jusqu'à présent: (@BalusC et tous les autres: je voudrais qu'ils soient concluants, mais sinon, ce qui précède peut être vrai et néanmoins les arguments peuvent aider toujours le lecteur à comprendre les différences/avantages/inconvénients/mauvaises/bonnes pratiques)

EJB vs bean géré

BalusC : C'est un EJB et non un bean géré, ce qui est assez différent. Les EJB s'exécutent en backend et les beans gérés en frontend. Les EJB s'exécutent également dans un contexte transactionnel. [...] Vous venez de confondre les beans enterprise 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 surestimez le sens/l'utilisation et cela me semble discutable. http://en.wikipedia.org/wiki/Enterprise_JavaBeans

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

Types de beans entreprise

Beans de session [3] qui peuvent être "avec état", "sans état" ou "singleton" [...]

Beans pilotés par message [...]

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

EJB Singleton vs bean à portée d'application

Verrouillage

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

mais:

(Je ne vois pas le marteau ici - désolé ...) Il est bon de connaître les valeurs par défaut de verrouillage (je n'en étais pas au courant), mais cela semble à nouveau incorrect: Oracle Java EE 6 Tutorial on Managing Concurrent Access in a Singleton Session Bean

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

Bien que par défaut, les singletons utilisent la concurrence gérée 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

16
Andreas Dietrich

@Singleton dans JSR-299 fait référence aux beans de session Singleton (javax.ejb.Singleton, ne pas javax.inject.Singleton), pas les beans gérés JSR-299 dans une portée intégrée appelée Singleton.

Vous trouverez peut-être sur votre serveur que @ApplicationScoped est un par EAR ou un par WAR/EJB-JAR car cela n'est pas clair dans la spécification, mais vous ne devez certainement pas vous attendre à ce qu'il soit un par JVM.

9
covener

Habituellement, lorsque vous ne souhaitez avoir qu'une seule instance d'un objet, vous devez probablement utiliser @ApplicationScoped annotation - un tel objet est mandaté et peut donc même être sérialisé correctement et prêt à l'emploi.

D'un autre côté, il existe également de nombreux cas où vous ne voulez qu'une seule instance de la classe, mais cette classe ne peut pas être mandatée (par exemple en raison de son caractère définitif) - alors @Singleton est un sauvetage. Parce que Singleton est une pseudo-portée et n'est pas mandatée comme toute portée "normale".

9
G. Demecki

Il y a encore une différence: @Singleton n'est pas un bean définissant des annotations, car la portée Singleton n'est pas une portée normale. Ensuite @ApplicationScoped est le bean définissant les annotations.

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

5
vigor

L'une des principales différences que vous pouvez écrire dans votre classe avec l'entrepreneur par défaut est le modificateur d'accès privé lors de l'utilisation de javax.inject.Singleton, mais votre classe doit avoir un entrepreneur par défaut avec au moins un modificateur d'accès par défaut lors de l'utilisation de javax.enterprise.context.ApplicationScoped et c'est JBOSS 6.1 GA Final la mise en oeuvre

2
user1017344