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…
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.
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é.
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.
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.
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 .
@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. 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. 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):
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.
HTML + CSS + Ajax + JQuery
Cadre de jeu
Utilisez le code Java pur aussi longtemps que possible. On peut faire la fusion des services Web ici.
XMLTool (Recherche sur Google Code), JSoup, Google GSon, XStream, JOOX (Recherche sur Google Code)
CRUD: JPA ou SienaProject ou QueryDSL / Requêtes complexes: JOOQ, QueryDSL
Voici mes 5 cents
Android, Angular.JS WebClient, OAUTHv2
REST, Jersey (JAX-RS), Jackson (dé / sérialisation JSON), objects DTO (différents des modèles de logique métier)
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.
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.
MySQL, Memcached, Redis
Ce que nous avons suivi dans notre projet est:
Technologie frontale
API
Logique d’entreprise
DONNÉES DE PRINTEMPS
Données SPRING MongoDB
Base de données
Serveur (pour la mise en cache)
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).
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:
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:
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