Qu'est-ce qu'un EJB et que fait-il?

151

J'ai essayé d'apprendre ce que EJBsont les beans, qu'est-ce que cela signifie que leurs instances sont gérées dans un pool, bla bla. Je ne peux vraiment pas les maîtriser.

Pouvez-vous m'expliquer ce qu'ils sont vraiment (pratiquement pour un programmeur Java)? Que font-ils? Quels sont leurs objectifs? Pourquoi vraiment les utiliser? (Pourquoi ne pas s'en tenir à POJO?) Peut-être un exemple d'application?

Veuillez vous référer uniquement aux informations mises à jour, c'est-à-dire EJB 3.1. Les informations datées sur EJB peuvent être trompeuses.

Pour les débutants en apprentissage EJB, veuillez noter:

Les EJB sont basés sur des objets distribués , c'est-à-dire des logiciels fonctionnant sur plusieurs machines (virtuelles ou physiques) reliées par un réseau .

jacktrades
la source

Réponses:

161

Pourquoi vraiment les utiliser? (Pourquoi ne pas s'en tenir à POJO?)

SI vous avez besoin d'un composant qui accède à la base de données, ou accède à d'autres ressources de connectivité / d'annuaire, ou est accessible à partir de plusieurs clients, ou est conçu comme un service SOA, les EJB d'aujourd'hui sont généralement "plus gros, plus puissants, plus rapides (ou au moins plus évolutifs) et plus simple que les POJO. Ils sont particulièrement utiles pour desservir un grand nombre d'utilisateurs sur le Web ou le réseau d'entreprise et un peu moins précieux pour les petites applications d'un service.

  1. Réutilisation / partage de logique sur plusieurs applications / clients avec le couplage lâche.
    Les EJB peuvent être empaquetés dans leurs propres fichiers JAR, déployés et appelés depuis de nombreux endroits. Ce sont des composants communs. Il est vrai que les POJO peuvent être (soigneusement!) Conçus comme des bibliothèques et emballés sous forme de fichiers JAR. Mais les EJB prennent en charge l'accès au réseau local et distant - y compris via l'interface Java locale, RMI transparent, message asynchrone JMS et service Web SOAP / REST, ce qui permet d'économiser des dépendances jar copier-coller avec plusieurs déploiements (incohérents?).
    Ils sont très utiles pour créer des services SOA. Lorsqu'ils sont utilisés pour l'accès local, ils sont des POJO (avec des services de conteneurs gratuits ajoutés). Le fait de concevoir une couche EJB séparée favorise une attention particulière pour maximiser l'encapsulation, le couplage et la cohésion lâches, et favorise une interface propre (façade), protégeant les appelants des modèles complexes de traitement et de données.

  2. Évolutivité et fiabilité Si vous appliquez un grand nombre de requêtes à partir de divers messages / processus / threads d'appel, elles sont d'abord distribuées sur les instances EJB disponibles dans le pool, puis mises en file d'attente. Cela signifie que si le nombre de demandes entrantes par seconde est supérieur à ce que le serveur peut gérer, nous nous dégradons en douceur - il y a toujours des demandes traitées efficacement et les demandes excédentaires sont mises en attente. Nous n'atteignons pas la «fusion» du serveur - où TOUTES les requêtes subissent simultanément un temps de réponse terrible, et le serveur essaie d'accéder à plus de ressources que le matériel et le système d'exploitation ne peuvent gérer et donc se bloque. Les EJB peuvent être déployés sur un niveau distinct pouvant être mis en cluster - cela garantit la fiabilité via le basculement d'un serveur à un autre, et le matériel peut être ajouté pour évoluer de manière linéaire.

  3. Gestion de la concurrence. Le conteneur garantit que les instances EJB sont automatiquement accédées en toute sécurité (en série) par plusieurs clients. Le conteneur gère le pool EJB, le pool de threads, la file d'attente d'appel et exécute automatiquement le verrouillage en écriture au niveau de la méthode (par défaut) ou en lecture (via @Lock (READ)). Cela protège les données de la corruption due à des conflits d'écriture-écriture simultanés et aide les données à être lues de manière cohérente en évitant les conflits de lecture-écriture.
    Ceci est principalement utile pour les beans session @Singleton, où le bean manipule et partage un état commun entre les appelants clients. Cela peut être facilement remplacé pour configurer manuellement ou contrôler par programme des scénarios avancés pour l'exécution de code simultanée et l'accès aux données.

  4. Traitement automatisé des transactions.
    Ne faites rien du tout et toutes vos méthodes EJB sont exécutées dans une transaction JTA. Si vous accédez à une base de données à l'aide de JPA ou JDBC, elle est automatiquement inscrite dans la transaction. Idem pour les appels JMS et JCA. Spécifiez @TransactionAttribute (someTransactionMode) avant une méthode pour spécifier si / comment cette méthode particulière participe à la transaction JTA, en remplaçant le mode par défaut: "Obligatoire".

  5. Accès très simple aux ressources / dépendances par injection.
    Le conteneur recherchera des ressources et définira des références de ressources en tant que champs d'instance dans l'EJB: comme les connexions JDBC stockées JNDI, les connexions / sujets / files d'attente JMS, d'autres EJB, les transactions JTA, les contextes de persistance du gestionnaire d'entités JPA, les unités de persistance d'usine du gestionnaire d'entités JPA, et Ressources de l'adaptateur JCA. par exemple pour configurer une référence à un autre EJB et une transaction JTA et un gestionnaire d'entités JPA et une fabrique de connexions JMS et une file d'attente:

    @Stateless
    public class MyAccountsBean {
    
        @EJB SomeOtherBeanClass someOtherBean;
        @Resource UserTransaction jtaTx;
        @PersistenceContext(unitName="AccountsPU") EntityManager em;
        @Resource QueueConnectionFactory accountsJMSfactory;
        @Resource Queue accountPaymentDestinationQueue;
    
        public List<Account> processAccounts(DepartmentId id) {
            // Use all of above instance variables with no additional setup.
            // They automatically partake in a (server coordinated) JTA transaction
        }
    }
    

    Un servlet peut appeler ce bean localement, en déclarant simplement une variable d'instance:

    @EJB MyAccountsBean accountsBean;    
    

    puis appelez simplement ses méthodes comme vous le souhaitez.

  6. Interaction intelligente avec JPA. Par défaut, l'EntityManager injecté comme ci-dessus utilise un contexte de persistance à portée de transaction. C'est parfait pour les beans session sans état. Lorsqu'une méthode EJB (sans état) est appelée, un nouveau contexte de persistance est créé dans la nouvelle transaction, toutes les instances d'objet d'entité extraites / écrites dans la base de données sont visibles uniquement dans cet appel de méthode et sont isolées des autres méthodes. Mais si d'autres EJB sans état sont appelés par la méthode, le conteneur se propage et partage le même PC avec eux, de sorte que les mêmes entités sont automatiquement partagées de manière cohérente via le PC dans la même transaction.
    Si un bean de session @Stateful est déclaré, une affinité intelligente égale avec JPA est obtenue en déclarant que le entityManager est une étendue étendue: @PersistentContent (unitName = "AccountsPU, type = EXTENDED). Cela existe pour la durée de vie de la session du bean, sur plusieurs appels et transactions bean, mise en cache des copies en mémoire des entités DB précédemment récupérées / écrites afin qu'elles n'aient pas besoin d'être récupérées à nouveau.

  7. La gestion du cycle de vie. Le cycle de vie des EJB est géré par conteneur. Selon les besoins, il crée des instances EJB, efface et initialise l'état du bean session avec état, passive et active et appelle les méthodes de rappel du cycle de vie, afin que le code EJB puisse participer aux opérations du cycle de vie pour acquérir et libérer des ressources, ou effectuer d'autres comportements d'initialisation et d'arrêt. Il capture également toutes les exceptions, les enregistre, annule les transactions selon les besoins et lève de nouvelles exceptions EJB ou @ApplicationExceptions selon les besoins.

  8. Gestion de la sécurité. Le contrôle d'accès basé sur les rôles aux EJB peut être configuré via une simple annotation ou un paramètre XML. Le serveur transmet automatiquement les détails de l'utilisateur authentifié avec chaque appel en tant que contexte de sécurité (le principal et le rôle appelant). Il garantit que toutes les règles RBAC sont automatiquement appliquées afin que les méthodes ne puissent pas être appelées illégalement par le mauvais rôle. Il permet aux EJB d'accéder facilement aux détails de l'utilisateur / du rôle pour une vérification programmatique supplémentaire. Il permet de connecter un traitement de sécurité supplémentaire (ou même des outils IAM) au conteneur de manière standard.

  9. Standardisation et portabilité. Les implémentations d'EJB sont conformes aux normes Java EE et aux conventions de codage, ce qui favorise la qualité et la facilité de compréhension et de maintenance. Il favorise également la portabilité du code vers les nouveaux serveurs d'applications des fournisseurs, en s'assurant qu'ils prennent tous en charge les mêmes fonctionnalités et comportements standard, et en décourageant les développeurs d'adopter accidentellement des fonctionnalités propriétaires
    non portables.

  10. Le vrai kicker: la simplicité. Tout ce qui précède peut être fait avec un code très simplifié - soit en utilisant les paramètres par défaut pour les EJB dans Java EE 6, soit en ajoutant quelques annotations. Le codage des caractéristiques de force d'entreprise / industrielle dans vos propres POJO serait beaucoup plus volumineux, complexe et sujet aux erreurs. Une fois que vous commencez à coder avec les EJB, ils sont plutôt faciles à développer et offrent un grand nombre d'avantages de "free ride".

Dans la spécification EJB originale d'il y a 10 ans, les EJB étaient un problème majeur de productivité. Ils étaient gonflés, avaient besoin de beaucoup d'artefacts de code et de configuration et fournissaient environ 2/3 des avantages ci-dessus. La plupart des projets Web ne les utilisaient pas réellement. Mais cela a considérablement changé avec 10 ans de peaufinage, de révision, d'amélioration fonctionnelle et de rationalisation du développement. Dans Java EE 6, ils offrent une force industrielle de niveau maximum et une simplicité d'utilisation.

Qu'est-ce qu'il ne faut pas aimer ?? :-) :-)

Glen Best
la source
67

Un EJB est un composant Java, contenant une logique métier, que vous déployez dans un conteneur, et qui bénéficie des services techniques fournis par le conteneur, généralement de manière déclarative, grâce aux annotations:

  • gestion des transactions: une transaction peut être lancée automatiquement avant qu'une méthode de l'EJB ne soit appelée, et validée ou annulée une fois que cette méthode est retournée. Ce contexte transactionnel est propagé aux appels vers d'autres EJB.
  • gestion de la sécurité: il est possible de vérifier que l'appelant a les rôles nécessaires pour exécuter la méthode.
  • injection de dépendances: d'autres EJB, ou des ressources comme un gestionnaire d'entités JPA, une source de données JDBC, etc. peuvent être injectés dans l'EJB.
  • concurrence: le conteneur s'assure qu'un seul thread à la fois appelle une méthode de votre instance EJB.
  • distribution: certains EJB peuvent être appelés à distance, depuis une autre JVM.
  • basculement et équilibrage de charge: les clients distants de vos EJB peuvent automatiquement voir leur appel redirigé vers un autre serveur si nécessaire.
  • gestion des ressources: les beans stateful peuvent être automatiquement passivés sur disque afin de limiter la consommation de mémoire de votre serveur.
  • ... J'ai probablement oublié certains points.
JB Nizet
la source
Quand vous parlez de transaction - vous parlez de persistance?
jacktrades
6
Oui, mais pas seulement. Les conteneurs EJB fournissent un gestionnaire de transactions JTA distribué, prenant en charge plusieurs ressources dans une seule transaction. Vous pouvez par exemple mettre à jour certaines données dans une base de données et envoyer des messages JMS en une seule transaction. Si quelque chose échouait, tout serait annulé: les mises à jour de la base de données et les messages envoyés.
JB Nizet
@JBNizet excusez-moi de commenter un ancien thread, mais PAS les frameworks EJB comme Spring fournissent ces services que vous avez mentionnés. Je ne comprends pas la différence
MoienGK
Les principes de base sont les mêmes. Spring a pris les idées des EJB et vice-versa. Mais l'API, la mise en œuvre, la manière de déployer et certaines fonctionnalités sont différentes.
JB Nizet
@JB Nizet Dans le modèle MVC, où placeriez-vous les EJB en général? Je dirais qu'ils appartiennent à la couche Model, même si je connais beaucoup de gens qui disent qu'ils sont des contrôleurs. Si les EJB contiennent une logique métier (vous avez dit qu'ils le font), alors ils sont une couche modèle par définition.
user107986
22

J'espère que ce document d'Oracle aidera quelqu'un comme moi à comprendre le sujet d'EJB d'une manière simple.

Qu'est-ce qu'un Enterprise Bean? Écrit dans le langage de programmation Java, un bean entreprise est un composant côté serveur qui encapsule la logique métier d'une application. La logique métier est le code qui remplit l'objectif de l'application. Dans une application de contrôle d'inventaire, par exemple, les beans entreprise peuvent implémenter la logique métier dans des méthodes appelées checkInventoryLevel et orderProduct. En invoquant ces méthodes, les clients peuvent accéder aux services d'inventaire fournis par l'application.

Avantages des beans entreprise Pour plusieurs raisons, les beans entreprise simplifient le développement de grandes applications distribuées. Tout d'abord, étant donné que le conteneur EJB fournit des services de niveau système aux beans entreprise, le développeur de bean peut se concentrer sur la résolution des problèmes métier. Le conteneur EJB, plutôt que le développeur de bean, est responsable des services au niveau du système tels que la gestion des transactions et l'autorisation de sécurité.

Deuxièmement, parce que les beans plutôt que les clients contiennent la logique métier de l'application, le développeur client peut se concentrer sur la présentation du client. Le développeur client n'a pas à coder les routines qui implémentent les règles métier ou accèdent aux bases de données. En conséquence, les clients sont plus légers, un avantage particulièrement important pour les clients qui fonctionnent sur de petits appareils.

Troisièmement, comme les beans entreprise sont des composants portables, l'assembleur d'applications peut créer de nouvelles applications à partir de beans existants. Ces applications peuvent s'exécuter sur n'importe quel serveur Java EE compatible à condition qu'elles utilisent les API standard.

Quand utiliser les beans entreprise Vous devez envisager d'utiliser les beans entreprise si votre application présente l'une des exigences suivantes:

L'application doit être évolutive. Pour accueillir un nombre croissant d'utilisateurs, vous devrez peut-être distribuer les composants d'une application sur plusieurs machines. Non seulement les beans enterprise d'une application peuvent s'exécuter sur différentes machines, mais leur emplacement restera transparent pour les clients.

Les transactions doivent garantir l'intégrité des données. Les beans entreprise prennent en charge les transactions, les mécanismes qui gèrent l'accès simultané aux objets partagés.

L'application aura une variété de clients. Avec seulement quelques lignes de code, les clients distants peuvent facilement localiser les beans entreprise. Ces clients peuvent être légers, variés et nombreux.

Tesfa Zelalem
la source
3

La question qui m'intéresse le plus est comment et où puis-je les utiliser. Pour comprendre cela, nous devons d'abord voir quels types d'EJB existent. Il existe 2 grandes catégories:

  1. Beans de session
  2. Beans pilotés par message

Considérons les Session Beans. Ils sont de 3 types:

  1. Avec état - ces composants conservent l'état et sont spécifiques à un client sur plusieurs demandes. Considérez-le comme une session. L'utilisation immédiate de ceux-ci pourrait être faite de paniers de magasin ou d'autres types de sessions (session de connexion, etc.)
  2. Stateless - ce sont des composants autonomes qui ne conservent pas les informations entre les demandes, mais ils sont uniques à l'utilisateur. Une utilisation immédiate qui me vient à l'esprit - Classes de service dans la couche service . Imaginez OrderService. Une autre grande utilisation de ceux-ci est d'exposer des services Web. Encore une fois, cela doit être dans la couche Service ou totalement séparé.
  3. Singleton - ce sont les beans qui existent par application et sont créés une fois et peuvent être réutilisés / consultés plusieurs fois. Immédiatement leConfiguration composant vient à l'esprit - où vous pouvez stocker les configurations au niveau de l'application et y accéder lorsque vous en avez besoin de n'importe où.

Désormais, le reste des capacités ou fonctionnalités peut être utilisé sur plusieurs couches dans de telles situations:

  • Sécurité - vous pouvez vérifier les autorisations avec une annotation sur la méthode appelée. Cela peut se produire dans la couche Service ainsi que dans Controller si vous le souhaitez.
  • Gestion des transactions - c'est le candidat évident dans la couche de service ou la couche de persistance
  • Injection de dépendance - sera à nouveau utilisée partout

Une grande utilisation dans les temps modernes sont les soi-disant microservices et architectures orientées services. Vous pouvez empaqueter certains composants de logique métier en tant qu'EJB et les distribuer dans toute l'organisation, pour être utilisés par plusieurs clients (par client ici, je veux dire d'autres applications back-end).

Etc. Maintenant, le gros inconvénient est que vous devenez très dépendant du conteneur EJB et bien que vous puissiez basculer entre 2 implémentations de référence, vous ne pourrez pas passer à quelque chose de plus léger - Tomcat par exemple. Mais pourquoi voudriez-vous sacrifier tous les avantages?

ACV
la source