Où utiliser des EJB 3.1 et CDI?
Je fais un Java EE en fonction du produit dans lequel je suis à l'aide de GlassFish 3 et EJB 3.1.
Ma demande a beans de session, un planificateur et utilise les services web. J'ai récemment est venu à connaître Apache TomEE, qui prend en charge Les contextes et l'Injection de Dépendance (CDI). GlassFish conteneur prend également en charge CDI.
Puis-je remplacer les beans de session où je n'ai pas besoin de toute fonction que la CDI n'a pas également fournit déjà? Et si alors, quels sont les avantages que je peux obtenir?
Vous devez vous connecter pour publier un commentaire.
Oui, vous pouvez combiner les deux CDI et EJB et obtenir quelques bons résultats. Il semble que vous utilisez
@WebService
et@Schedule
, qui sont de bonnes raisons pour l'ajout d'EJB au mélange.Il y a beaucoup de confusion là-bas, voici donc quelques informations générales sur les EJB et CDI comme ils se rapportent à chacun d'eux.
EJB >= CDI
Noter que les Ejb sont CDI haricots et, par conséquent, avoir tous les avantages de CDI. L'inverse n'est pas vrai (encore). Donc, définitivement, ne pas entrer dans l'habitude de penser "EJB vs CDI" en tant que logique de vraiment se traduit par "EJB+CDI vs CDI", qui est d'un drôle d'équation.
Dans les futures versions de Java EE, nous allons continuer à nous aligner. Ce que l'alignement des moyens est de permettre aux gens de faire ce qu'il peut déjà le faire, juste sans les
@Stateful
,@Stateless
ou@Singleton
annotation en haut.EJB et CDI dans la mise en Œuvre des Termes
En fin de compte, EJB et CDI partagent la même conception fondamentale de l'être mandaté composants. Lorsque vous obtenez une référence à un EJB ou CDI bean, il n'est pas le réel bean. Plutôt l'objet vous est donné, c'est un fake (un proxy). Lorsque vous appelez une méthode sur ce faux objet, l'appel est acheminé vers le conteneur qui va envoyer l'appel à l'aide de séparateurs, décorateurs, etc. ainsi que de prendre soin de toute transaction ou de contrôles de sécurité. Une fois que tout cela est fait, l'appel se passe enfin à l'objet réel et le résultat est transmis par le mandataire de l'appelant.
La seule différence vient de la façon dont l'objet doit être invoquée est résolu. En "résolu", on veut simplement dire, où et comment le conteneur cherche le vrai exemple pour appeler.
En CDI le conteneur se regarde dans un "champ d'application", qui sera essentiellement une hashmap qui vit une période de temps spécifique (par demande
@RequestScoped
, par Session HTTP@SessionScoped
, par application@ApplicationScoped
, JSF Conversation@ConversationScoped
, ou par votre portée personnalisée mise en œuvre).Dans le conteneur d'EJB regarde aussi dans une hashmap si le bean est de type
@Stateful
. Un@Stateful
de haricots peuvent également utiliser l'un de ces annotations amenant à vivre et à mourir avec tous les autres haricots dans le champ d'application. Dans EJB@Stateful
est essentiellement la "toute l'étendue" de la fève. Le@Stateless
est essentiellement une instance de la piscine-vous obtenir une instance de la piscine pour la durée d'une invocation. Le@Singleton
est essentiellement@ApplicationScoped
Donc à un niveau fondamental, tout ce que vous pouvez faire avec un "EJB" bean vous devriez être en mesure de le faire avec un "CDI" bean. Sous les couvertures, il est terriblement difficile de les distinguer. Toute la plomberie est le même à l'exception de la façon dont les instances sont résolus.
Ils ne sont pas actuellement le même en termes de services le conteneur offre quand vous faites cela, l'utilisation de proxy, mais comme je l'ai dit, nous travaillons à la Java EE spec niveau.
Performance remarque
Abstraction de toute "la lumière" ou "lourd" images mentales que vous pourriez avoir. C'est tout le marketing. Ils ont la même conception interne, pour la plupart. CDI exemple la résolution est peut-être un peu plus complexe, car il est un peu plus dynamique et contextuelle. EJB exemple la résolution est assez statique, bête et simple en comparaison.
Je peux vous dire qu'à partir d'une perspective de mise en œuvre dans TomEE, il y a environ zéro différence de performances entre invoquant un EJB vs invoquant un bean CDI.
Défaut de Pojo, puis CDI, puis EJB
Bien sûr, n'utilisez pas de CDI ou EJB quand il n'y a aucun avantage. Jeter en CDI lorsque vous commencez à vouloir injection, les événements, les intercepteurs, les décorateurs, le cycle de vie de suivi et des choses comme ça. C'est la plupart du temps.
Au-delà de ces principes de base, il y a un certain nombre de services de conteneurs vous avez uniquement la possibilité d'utiliser si vous faites votre bean CDI aussi un EJB par l'ajout de
@Stateful
,@Stateless
, ou@Singleton
sur elle.Voici une courte liste de quand j'ai casser l'Ejb.
À l'aide de JAX-WS
Exposer un JAX-WS
@WebService
. Je suis paresseux. Lorsque le@WebService
est aussi un EJB, vous n'avez pas de liste et de la carte comme une servlet dans leweb.xml
fichier. C'est un travail pour moi. En Plus je obtenir la possibilité de l'utilisation des autres fonctionnalités mentionnées ci-dessous. C'est donc une évidence pour moi.Disponible à
@Stateless
et@Singleton
seulement.À l'aide de JAX-RS
Exposer un JAX-RS des ressources via
@Path
. Je suis toujours paresseux. Lorsque le service RESTful est aussi un EJB, encore une fois, vous obtenez automatiquement la découverte et n'ont pas à l'ajouter à une JAX-RSApplication
sous-classe ou quelque chose comme ça. En Plus je peux exposer exactement la même bean comme un@WebService
si je veux ou utiliser les fonctionnalités mentionnées ci-dessous.Disponible à
@Stateless
et@Singleton
seulement.De démarrage logique
Charger au démarrage via
@Startup
. Il n'y a actuellement pas d'équivalent à ce en CDI. En quelque sorte, nous avons manqué d'ajouter quelque chose comme unAfterStartup
événement dans le conteneur du cycle de vie. On a fait cela, il vous suffit peut avoir eu un@ApplicationScoped
de haricots, à l'écoute et qui serait effectivement la même que pour un@Singleton
avec@Startup
. C'est sur la liste pour le CDI 1.1.Disponible à
@Singleton
seulement.De travail en Parallèle
@Asynchronous
invocation de méthode. Départ de threads n'est pas à côté serveur de l'environnement. Avoir trop de threads est une grave performance killer. Cette annotation permet de paralléliser les choses que vous faites à l'aide du conteneur pool de threads. C'est génial.Disponible à
@Stateful
,@Stateless
et@Singleton
.Planification du travail
@Schedule
ouScheduleExpression
est fondamentalement un cron ouQuartz
fonctionnalité. Également très impressionnant. La plupart des conteneurs suffit d'utiliser le Quartz sous les couvertures pour cela. La plupart des gens ne savent pas, cependant, que la planification du travail dans Java EE est transactionnelle! Si vous mettez à jour une base de données puis de prévoir un peu de travail et l'un d'eux échoue, les deux seront automatiquement supprimés. Si leEntityManager
persistent appel échoue ou il y a un problème de rinçage, il n'y a pas besoin de l'onu-planifier le travail. Yay, les transactions.Disponible à
@Stateless
et@Singleton
seulement.À l'aide de EntityManagers dans une transaction JTA
La remarque ci-dessus sur les transactions des cours nécessite l'utilisation d'un
JTA
géréEntityManager
. Vous pouvez les utiliser avec de la plaine "CDI", mais sans le container-managed transactions, il peut être vraiment monotone dupliquer leUserTransaction
commit/rollback logique.Disponible pour tous les composants Java EE, y compris CDI, JSF
@ManagedBean
,@WebServlet
,@WebListener
,@WebFilter
, etc. Le@TransactionAttribute
annotation, cependant, est disponible à@Stateful
,@Stateless
et@Singleton
seulement.Garder JTA géré
EntityManager
La
EXTENDED
géréEntityManager
vous permet de garder unEntityManager
ouvert entreJTA
transactions et de ne pas perdre les données en cache. Bonne fonctionnalité pour le moment et au bon endroit. Utiliser de façon responsable 🙂Disponible à
@Stateful
seulement.Facile de synchronisation
Lorsque vous avez besoin de synchronisation, le
@Lock(READ)
et@Lock(WRITE)
annotations sont vraiment excellents. Il vous permet d'obtenir l'accès simultané de gestion pour gratuit. Sauter tous les ReentrantReadWriteLock de plomberie. Dans le même seau est@AccessTimeout
, ce qui vous permet de dire combien de temps un thread doit attendre pour accéder à la fève instance avant d'abandonner.Disponible à
@Singleton
haricots.@Stateful @SessionScoped
pojo, de son état: atomique entier, et une méthode qui getsAndIncrements. À partir d'un appel de service web de cette méthode. Essayez d'injecter le haricot, le service web comme CDI (@Inject
) et puis comme les EJB(@EJB
), faire plusieurs demandes de la même session, a remarqué la différence? Donc, plutôt que d'EJB >= CDI plus EJB != CDI.Stateless
etSingleton
fèves de JAX-RS ou JAX-WS web services. Toute utilisation de sessions HTTP ouStateful
haricots avec JAX-RS ou JAX-WS est non portable.@EJB
vs@Inject
les deux peuvent être utilisés pour injecter de l'Ejb developer.jboss.org/thread/179388, et la seconde considère la portée, pour@Stateful
Ejb qui est. Ma miss, l'idée était que l'injection à l'aide de @Inject seulement injecte de l'ejb comme un CDI, dans le conteneur CDI, donc pas de concurrence, asynch, la gestion des transactions, etc ont été fournis.@Observes(during=...)?
. Pourquoi n'est-il pas possible de "s'inscrire" un événement commeAFTER_SUCCESS
/AFTER_COMPLETION
... dans les Ejb de code avec un contexte défini être appelée après qu'une transaction a été fini? - Ce qui est souvent utilisé de cas d'utilisation - il semble être seulement possible avec le CDI?! - J'apprécierais aussi, si vous pourriez nous expliquer ce que @Petr Benes demandé: Whats sur les conteneurs pour le CDI haricots / Ejb, si on mélange les deux? - Merci à l'avance pour une petite mise à jour 🙂si vous êtes vraiment pas à l'aide de l'une des caractéristiques de l'ejb 3.1 la réponse est simple. mais devinez votre questiion indique que vous soupçonnez il y a des ejb 3.1 conceptes vous profitent, sans être au courant d'entre eux. un exemple pourrait être que le conteneur peut maintenir un pool de slsb prêt à être utilisé, de sorte que jms et connexions de base de données n'avez pas injecté dans le cadre de la demande