Décrivez l’architecture que vous utilisez pour les applications Web Java?

Partageons les architectures d’applications Web basées sur Java!

Il existe de nombreuses architectures différentes pour les applications Web à implémenter en Java. Les réponses à cette question peuvent servir de bibliothèque de diverses conceptions d’applications Web avec leurs avantages et leurs inconvénients. Bien que je réalise que les réponses seront subjectives, essayons d’être aussi objectives que possible et de motiver les avantages et les inconvénients que nous énumérons.

Utilisez le niveau de détail que vous préférez pour décrire votre architecture. Pour que votre réponse soit utile, vous devez au moins décrire les principales technologies et idées utilisées dans l’architecture que vous décrivez. Et last but not least, quand devrions-nous utiliser votre architecture?

Je vais commencer…


Vue d’ensemble de l’architecture

Nous utilisons une architecture à trois niveaux basée sur des normes ouvertes de Sun telles que Java EE, Java Persistence API, Servlet et Java Server Pages.

  • Persistance
  • Entreprise
  • Présentation

Les stream de communication possibles entre les couches sont représentés par:

Persistence  Business  Presentation 

Ce qui signifie par exemple que la couche de présentation n’appelle ni n’effectue jamais d’opérations de persistance. Elle le fait toujours via la couche de gestion. Cette architecture est conçue pour répondre aux exigences d’une application Web à haute disponibilité.

Persistance

Effectue des opérations de persistance de création, lecture, mise à jour et suppression ( CRUD ). Dans notre cas, nous utilisons JPA ( Java Persistence API ) et nous utilisons actuellement Hibernate comme fournisseur de persistance et utilisons son EntityManager .

Cette couche est divisée en plusieurs classes, où chaque classe traite d’un certain type d’entités (c.-à-d. Les entités associées à un panier peuvent être gérées par une seule classe de persistance) et est utilisée par un seul gestionnaire .

En outre, cette couche stocke également les entités JPA , telles que Account , ShoppingCart etc.

Entreprise

Toute la logique liée à la fonctionnalité de l’application Web se trouve dans cette couche. Cette fonctionnalité pourrait être un transfert d’argent pour un client qui souhaite payer un produit en ligne avec sa carte de crédit. Cela pourrait tout aussi bien être de créer un nouvel utilisateur, de supprimer un utilisateur ou de calculer le résultat d’une bataille dans un jeu basé sur le Web.

Cette couche est divisée en plusieurs classes et chacune de ces classes est annotée avec @Stateless pour devenir un bean session sans état (SLSB). Chaque SLSB est appelé gestionnaire et, par exemple, un gestionnaire peut être une classe annotée, appelée AccountManager .

Lorsque AccountManager doit effectuer des opérations CRUD, il effectue les appels appropriés à une instance de AccountManagerPersistence , qui est une classe de la couche de persistance. Une ébauche de deux méthodes dans AccountManager pourrait être:

 ... public void makeExpiredAccountsInactive() { AccountManagerPersistence amp = new AccountManagerPersistence(...) // Calls persistence layer List expiredAccounts = amp.getAllExpiredAccounts(); for(Account account : expiredAccounts) { this.makeAccountInactive(account) } } public void makeAccountInactive(Account account) { AccountManagerPersistence amp = new AccountManagerPersistence(...) account.deactivate(); amp.storeUpdatedAccount(account); // Calls persistence layer } 

Nous utilisons des transactions de gestion de conteneurs afin de ne pas avoir à effectuer de démarcations de transactions. Ce qui se passe fondamentalement sous le capot est que nous initions une transaction lorsque vous entrez la méthode SLSB et que vous la validez (ou l’annulez) immédiatement avant de quitter la méthode. C’est un exemple de convention sur la configuration, mais nous n’avons eu besoin de rien d’autre que la configuration par défaut, Obligatoire, pour le moment.

Voici comment le didacticiel Java EE 5 de Sun explique l’ atsortingbut de transaction requirejs pour Enterprise JavaBeans (EJB):

Si le client est exécuté dans une transaction et appelle la méthode du bean enterprise, la méthode s’exécute dans la transaction du client. Si le client n’est pas associé à une transaction, le conteneur lance une nouvelle transaction avant d’exécuter la méthode.

L’atsortingbut Obligatoire est l’atsortingbut de transaction implicite pour toutes les méthodes de bean enterprise exécutées avec une démarcation de transaction gérée par conteneur. En règle générale, vous ne définissez pas l’atsortingbut Obligatoire, sauf si vous devez remplacer un autre atsortingbut de transaction. Les atsortingbuts de transaction étant déclaratifs, vous pouvez facilement les modifier ultérieurement.

Présentation

Notre couche de présentation est en charge de … la présentation! Il est responsable de l’interface utilisateur et affiche des informations à l’utilisateur en créant des pages HTML et en recevant les entrées de l’utilisateur via les requêtes GET et POST. Nous utilisons actuellement l ‘ancienne combinaison Servlet ‘ Java Server Pages ( JSP ).

La couche appelle des méthodes dans les gestionnaires de la couche de gestion pour effectuer les opérations demandées par l’utilisateur et pour recevoir des informations à afficher dans la page Web. Parfois, les informations reçues de la couche de gestion sont des types moins complexes que ceux de Ssortingng et integers, et parfois des entités JPA .

Avantages et inconvénients avec l’architecture

Avantages

  • Avoir tout ce qui concerne une manière spécifique de faire de la persistance dans cette couche signifie seulement que nous pouvons passer de l’utilisation de JPA à autre chose, sans avoir à réécrire quoi que ce soit dans la couche de gestion.
  • Il est facile pour nous d’échanger notre couche de présentation en quelque chose d’autre, et il est probable que nous le ferons si nous trouvons quelque chose de mieux.
  • Il est intéressant de laisser le conteneur EJB gérer les limites des transactions.
  • L’utilisation de Servlet + JPA est facile (pour commencer) et les technologies sont largement utilisées et implémentées sur de nombreux serveurs.
  • L’utilisation de Java EE est censée faciliter la création d’un système à haute disponibilité avec un équilibrage de charge et un basculement . Les deux dont nous pensons que nous devons avoir.

Les inconvénients

  • En utilisant JPA, vous pouvez stocker des requêtes souvent utilisées en tant que requêtes nommées à l’aide de l’annotation @NamedQuery sur la classe d’entités JPA. Si vous avez autant que possible en rapport avec la persistance dans les classes de persistance, comme dans notre architecture, cela répartira les emplacements où vous pouvez également trouver des requêtes pour inclure les entités JPA. Il sera plus difficile de donner un aperçu des opérations de persistance et donc plus difficile à maintenir.
  • Nous avons des entités JPA dans le cadre de notre couche de persistance. Mais Account et ShoppingCart , ne sont-ils pas vraiment des objects métier? Cela se fait de cette façon, car vous devez toucher ces classes et les transformer en entités que JPA sait gérer.
  • Les entités JPA, qui sont également nos objects métier, sont créées comme des objects de transfert de données ( DTO ), également appelés objects de valeur (VO). Cela se traduit par un modèle de domaine anémique, car les objects métier n’ont pas de logique à part les méthodes d’accesseur. Toute la logique est faite par nos gestionnaires dans la couche de gestion, ce qui se traduit par un style de programmation plus procédural. Ce n’est pas un bon design orienté object, mais ce n’est peut-être pas un problème? (Après tout, l’orientation de l’object n’est pas le seul paradigme de programmation qui a donné des résultats.)
  • L’utilisation d’EJB et de Java EE introduit un peu de complexité. Et nous ne pouvons pas utiliser uniquement Tomcat (l’ajout d’un micro-conteneur EJB n’est pas purement Tomcat).
  • L’utilisation de Servlet + JPA pose de nombreux problèmes. Utilisez Google pour plus d’informations sur ces problèmes.
  • Lorsque les transactions sont fermées lors de la sortie de la couche de gestion, nous ne pouvons pas charger les informations des entités JPA configurées pour être chargées depuis la firebase database (en utilisant fetch=FetchType.LAZY ) depuis la couche de présentation. Cela déclenchera une exception. Avant de retourner une entité contenant ces types de champs, nous devons être sûrs d’appeler les getter appropriés. Une autre option consiste à utiliser le langage de requête Java Persistence ( JPQL ) et à effectuer un FETCH JOIN . Cependant, ces deux options sont un peu lourdes.

Ok je vais faire un (plus court):

  • Frontend: Tapestry (3 pour les projets plus anciens, 5 pour les projets plus récents)
  • Couche entreprise: spring
  • DAO’s: Ibatis
  • Base de données: Oracle

Nous utilisons le support de transaction Sping et démarrons les transactions en entrant dans la couche de service, en se propageant jusqu’à l’appel DAO. La couche Service a le plus de connaissances sur les modèles de bussines, et les DAO effectuent un travail CRUD relativement simple.

Certaines requêtes plus compliquées sont gérées par des requêtes plus compliquées dans le backend pour des raisons de performances.

Avantages de l’utilisation de Spring dans notre cas: nous pouvons avoir des instances dépendantes de pays / langue, qui sont derrière une classe Spring Proxy. En fonction de l’utilisateur de la session, l’implémentation correcte du pays / de la langue est utilisée lors d’un appel.

La gestion des transactions est presque transparente, annulation des exceptions d’exécution. Nous utilisons les exceptions non vérifiées autant que possible. Nous avions l’habitude de faire des exceptions vérifiées, mais avec l’introduction de Spring, je vois les avantages des exceptions non contrôlées, ne gérant que les exceptions quand vous le pouvez. Cela évite beaucoup de choses “catch / rethrow” ou “throws”.

Désolé, c’est plus court que ton post, j’espère que tu trouves ça intéressant …

Technologies de développement Web basées sur Java idéales aujourd’hui.

Couche Web:

HTML + CSS + Ajax + JQuery

RESTFul Web Controller / Couche de traitement des actions / requêtes:

Cadre de jeu

Business Logic / Service Layer:

Utilisez le code Java pur aussi longtemps que possible. On peut faire la fusion des services Web ici.

Couche de transformation de données XML / JSon:

XMLTool (Recherche sur Google Code), JSoup, Google GSon, XStream, JOOX (Recherche sur Google Code)

Couche de persistance:

CRUD: JPA ou SienaProject ou QueryDSL / Requêtes complexes: JOOQ, QueryDSL

Voici mes 5 cents

Présentation

Android, Angular.JS WebClient, OAUTHv2

API

REST, Jersey (JAX-RS), Jackson (dé / sérialisation JSON), objects DTO (différents des modèles de logique métier)

Logique d’entreprise

Printemps pour DI et gestion des événements. DDD-ish approche des objects du modèle. Les tâches en cours d’exécution plus longues sont déchargées avec SQS dans les modules de travail.

DAO

Modèle de référentiel avec des modèles JDBC Spring pour stocker des entités. Redis (JEDIS) pour les classements, en utilisant les listes ordonnées. Memcache pour Token Store.

Base de données

MySQL, Memcached, Redis

Ce que nous avons suivi dans notre projet est:

Technologie frontale

  • AngularJS
  • HTML5
  • css3
  • Javascript
  • Bootstrap 3

API

  1. DU REPOS
  2. JERSEY (JAX-RS)
  3. REPOS ASSURÉ
  4. BOTTE DE PRINTEMPS
  5. Jackson
  6. sécurité de spring

Logique d’entreprise

  • DONNÉES DE PRINTEMPS

  • Données SPRING MongoDB

Base de données

  • MongoDB

Serveur (pour la mise en cache)

  • redis

Nous utilisons toujours la stack Struts-Spring-Hibernate habituelle.

Pour les applications futures, nous étudions les services Web Spring Web Flow + Spring MVC + Hibernate ou Spring + Hibernate + avec l’interface frontale Flex.

Une caractéristique distincte de notre architecture est la modularisation. Nous avons un certain nombre de modules, certains commençant par 3 à 30 tables maximum dans la firebase database. La plupart des modules sont composés de projets commerciaux et Web. Business project conserve la logique métier et de persistance tandis que Web contient la logique de présentation.
Au niveau logique, il existe trois couches: Business, Persistence et Presentation.
Dépendances:
La présentation dépend de l’activité et de la persistance.
La persistance dépend des affaires.
Les affaires ne dépendent pas d’autres couches.

La plupart des projets d’entreprise ont trois types d’interfaces (note: pas d’interface graphique, c’est une couche d’interface Java programmée).

  1. Interface utilisée par la présentation en tant que client
  2. Interface utilisée par les autres modules lorsqu’ils sont le client du module.
  3. Interface pouvant être utilisée à des fins administratives du module.

Souvent, 1 étend 2. Ainsi, il est facile de remplacer une implémentation de module par une autre. Cela nous aide à adopter différents clients et à nous intégrer plus facilement. Certains clients n’achèteront que certains modules et devront intégrer des fonctionnalités déjà existantes. Puisque l’interface et la couche d’implémentation sont séparées, il est facile de déployer l’implémentation du module ad-hock pour ce client spécifique sans affecter les modules dépendants. Et Spring Framework facilite l’injection de différentes implémentations.

Notre couche métier est basée sur les POJO. Une tendance que j’observe est que ces POJO ressemblent à des DTO. Nous souffrons d’un modèle de domaine anémique . Je ne suis pas sûr de savoir pourquoi cela se produit, mais cela peut être dû à la simplicité du domaine problématique de la plupart de nos modules, la plupart du travail est dû au fait que les développeurs préfèrent placer la logique ailleurs.

Voici une autre architecture Web sur laquelle j’ai travaillé:

L’une des principales exigences était que l’application devrait prendre en charge les mobiles / autres appareils. L’application doit également être extensible ou flexible aux changements de choix technologiques.

Niveau de présentation:

  • JSP / JQuery (MVC côté client)
  • Native Android
  • IPhone natif
  • Web mobile (HTML5 / CSS3 / Conception adaptative)

  • Contrôleurs Spring REST (peuvent changer pour JAX-RS)

Niveau de service métier:

Spring @Service (peut changer pour EJB sans état)

Niveau d’access aux données:

Spring @Repository (Peut changer pour EJB Stateless)

Niveau de ressource:

Entités Hibernate (JPA) (peut changer pour n’importe quel ORM)

Vous pouvez trouver plus d’informations sur le livre qui suit cette architecture ici .

IMHO, la plupart d’entre nous ont un dénominateur commun. Au moins dans le back-end, nous avons une forme de conteneur IOC / DI et un cadre de persistance. Personnellement, j’utilise Guice et Mybatis pour cela. Les différences concernent la manière dont nous implémentons la couche de vue / interface utilisateur / présentation. Il y a deux options majeures ici (peut-être plus). Basées sur des actions (URL mappées sur des contrôleurs) et sur des composants. J’utilise actuellement une couche de présentation basée sur des composants (en utilisant un guichet). Il imite parfaitement un environnement de bureau où j’utilise des composants et des événements, par opposition aux URL et aux contrôleurs. Je suis actuellement à la recherche d’une raison pour laquelle je devrais migrer vers ce type d’architecture de contrôleur d’URL (c’est ainsi que je me suis retrouvé sur cette page). Pourquoi le battage médiatique sur les architectures RESTful et Stateless?

Pour répondre à cette question en bref: j’écris des applications web avec un framework orienté composants au-dessus du conteneur Guice IOC et place des données dans une firebase database relationnelle en utilisant Mybatis.

Un peu différent, et je revendiquerais plus d’architecture java modulaire ici. Nous avons:

  1. Ressort avant WS / Rest / JSP
  2. Spring MVC pour la logique de service métier, contenant la logique de la couche de présentation ainsi que les transactions Spring
  3. Interface de communication de service de composants, recherchée par EJB par les services métier. Les EJB définissent leurs propres limites de transaction pouvant être associées à des transactions Spring.
  4. Implémentations du service de composants, encore une fois Composants Spring
  5. Couche d’intégration, MyBatis pour les intégrations de bases de données, Spring WS pour les intégrations de services Web, autres technologies d’intégration pour d’autres services
  6. Mainframes, bases de données, autres services sur d’autres serveurs …

En plus de ce qui précède, nous avons les modules de bibliothèque partagés qui sont des fournisseurs de fonctionnalités communes pour tous les services.

L’utilisation de différentes couches nous permet un découplage complet et la modularité dont nous avons besoin. Nous sums également en mesure d’utiliser pleinement la puissance de Java EE et de Spring. Rien ne nous empêche d’utiliser JSF, par exemple, pour le front-end si nécessaire.

Comparé à l’exemple d’architecture par OP, je pense que cela peut être décrit comme ayant quatre couches principales au lieu de trois, avec toutefois une torsion.

J’ai travaillé sur des projets qui utilisent ce modèle de gestionnaire rigide. Historiquement, j’étais un grand partisan de la hiérarchie rigide où tout se rangeait dans une boîte soignée. Au fur et à mesure que je progresse dans ma carrière, je le trouve forcé dans beaucoup de cas. Je pense qu’adopter un état d’esprit plus agile en matière de conception d’applications conduit à un meilleur produit. Ce que je veux dire par là créer un ensemble de classes qui résolvent le problème en question. Plutôt que de dire “Avez-vous créé un manager pour ceci et cela?”

Le projet actuel sur lequel je travaille est une application Web combinant les appels Spring MVC et RestEasy JSON / Ajax. Côté serveur, nos contrôleurs intègrent un niveau de données basé sur une façade judicieuse avec JPA / Hibernate pour un access direct à la firebase database, certains access EJB et certains appels de services Web SOAP. Tout cela ensemble est un code de contrôleur Java personnalisé qui détermine ce qu’il faut sérialiser en tant que JSON et retourner au client.

Nous passons presque tout notre temps à essayer de créer un modèle unifié plutôt que d’adopter l’idée «Pire, c’est mieux» de la philosophie de conception Unix. Il est préférable de colorer les lignes et de construire quelque chose de sensible, rapidement, que de créer quelque chose qui adhère à un ensemble de mandats de conception rigoureux.

Les composants de l’ architecture d’application Web incluent:

1: navigateur: interaction client

  HTML JavaScript Stylesheet 

2: Internet

3: serveur Web

  CSS Image Pages(Java render ) 

4: serveur d’applications

  App Webapp (Java interaction) Others WebApps 

5: Serveur de firebase database

  Oracle, SQL, MySQL 

6: données