Je travaille sur une application Spring-MVC dans laquelle nous utilisons Maven pour la gestion des dépendances. Comme le projet est grand, nous pensons à diviser le projet en plusieurs parties. J'avais des doutes, et j'espère que j'obtiendrai des réponses ici.
Actuellement, nous déployons un seul fichier WAR en tant que ROOT.war
sur Apache Tomcat sur notre serveur. Comme le projet est grand, il y a des parties dans la webapp comme les notifications et les e-mails, les services tiers, Push (Cometd), les API REST, etc. Actuellement, tous sont matraqués et dépendent les uns des autres. Par exemple, l'objet Notification
dépend également de l'objet Person
, car les notifications sont adaptées aux utilisateurs.
L'intention principale de diviser le grand projet est de pouvoir travailler sur des modules individuels, pour des corrections de bugs, l'ajout de fonctionnalités, des tests, etc. Et lorsque satisfait, seul ce module peut être remplacé sur le serveur au lieu de l'application entière. Est-ce possible?
Comme je l'ai déjà mentionné précédemment, il existe des dépendances et des mappages entre les objets. Comment ceux-ci seront-ils gérés à travers différents sous-modules, ou est-ce que les instructions d'importation changeront pour inclure d'autres projets?
Comme je l'ai dit, l'intention est de travailler sur des modules individuels et de pouvoir les déployer (de préférence à chaud). Actuellement, nous n'avons qu'un seul fichier WAR en tant que ROOT.war
. Le fractionnement créera-t-il plusieurs fichiers de guerre, qui sont ensuite appelés par URL comme domain-name.com/module_name/some_mapping
?
Je vérifie actuellement la documentation, mais c'est l'objectif principal que nous voulons atteindre avec le module multi fourni par Maven et intéressé à savoir si cela est possible. Si d'autres informations sont nécessaires, veuillez me le faire savoir.
Actuellement, j'utilise un POM parent du printemps comme suit:
<parent>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>1.1.3.RELEASE</version>
<relativePath />
</parent>
Est-ce possible?
Oui certainement. J'ai dans le passé structuré quelques projets comme celui-ci, voici quelques morceaux qui, je l'espère, vous aideront à démarrer.
Il y a deux caractéristiques principales de Maven que vous utiliserez pour tisser des choses ensemble:
Vous devrez diviser vos projets en plusieurs projets indépendants. Ici, par indépendant, je veux dire que toutes les références au code en dehors du projet se font via des dépendances dans Maven et non pas en fusionnant directement l'arborescence source.
Selon l'état de votre arborescence source, cela pourrait représenter beaucoup de travail. Cela dit, vous ne le faites pas pour chausse-pied à Maven, mais plutôt comme un moyen de structurer et de désinfecter votre base de code. Considérez-le comme votre boîte à outils, beaucoup plus facile de trouver des choses ici:
qu'ici:
Maven s'appuie fortement sur convention donc mieux vous organisez vos affaires, plus Maven peut vous aider. Cela dit, cela peut vous obliger à vous réorganiser pour mieux correspondre à sa propre convention et si je dois donner un conseil ici, c'est qu'il est BEAUCOUP plus facile de modifier vos données pour qu'elles correspondent aux conventions de Maven que d'essayer de configurer Maven pour comprendre votre convention.
Si ces projets pouvaient être utilisables en dehors de l'application principale, ils pourraient vivre en tant que bibliothèques véritablement indépendantes et incluses via des dépendances maven. Ils doivent vivre dans leur propre référentiel (pas dans l'arborescence source de l'application) et ne doivent dépendre d'aucune partie de l'application principale.
Les parties centrales de votre application, une fois divisées en projets, peuvent être regroupées sous forme de modules. En règle générale, vous les placerez comme sous-dossier du dossier source principal de votre application.
Votre POM parent pour votre application contiendra également la déclaration du module. Vous y placerez également toutes les dépendances courantes pour votre application ainsi que la plupart des plugins de build et leur configuration. Ici aussi, je vous recommande vivement de placer un groupe de propriétés pour des choses telles que la version de l'application que vous pouvez réutiliser dans les modules. Il est beaucoup plus facile à gérer lorsque tout a la même version et le fait d'avoir la version au même endroit fait que cela fonctionne.
Si vous êtes une équipe plus grande que 1, je vous recommande également fortement d'installer un référentiel pour vos dépendances Maven. Regardez Artifactory , Nexus ou Archiva . Vous pouvez configurer le fichier POM pour qu'il s'installe directement sur ceux-ci, donc une fois exécuté, cela ne devrait pas être une surcharge, mais cela fera gagner beaucoup de temps à votre équipe pour résoudre les dépendances avec le bon pot au bon endroit.
Concernant l'outillage, la prochaine étape logique est ici un système d'intégration continue ( Jenkins , il y en a beaucoup plus). Il gérera la construction de la source en exécutant les tests et en poussant vers l'artifactory, avec tout cela en place, tout ce que vous avez à faire est de travailler le code et le reste fonctionne.
Puisque vous empaquetez votre application comme une guerre maven peut gérer la construction de la guerre et placez toutes les dépendances à leur place sans avoir à fusionner les fichiers jar ou autres travaux similaires, donc pas de soucis là-bas.
Je pourrais continuer beaucoup plus longtemps ici mais rien ne vaut un bon exemple. Recherchez sur github des projets de même ampleur et voyez comment ils ont construit leurs fichiers pom et leurs hiérarchies de dossiers. Regardez plus d'un, certains s'adapteront mieux à votre configuration que d'autres, aucun n'incarne vraiment le vérité mais vous devriez en trouver suffisamment pour alimenter vos réflexions sur la façon de le faire.
Prenez Jenkins par exemple:
Vous pouvez voir que leur parent POM est assez étendu.
Ils utilisent des modules comme vous pouvez le voir dans cette section:
<modules>
<module>core</module>
<module>war</module>
<module>test</module>
<module>cli</module>
</modules>
Et à chaque module correspond un sous-dossier du même nom qui contient également un POM. Vous pouvez en imbriquer autant que vous le souhaitez, mais gardez-le dans les niveaux de santé mentale;).
Si vous n'avez jamais utilisé Maven, je vous suggère de ne pas commencer tout de suite avec les modules. Allez-y lentement, commencez par dire l'une des bibliothèques les plus simples que vous puissiez avoir et faites-en un projet maven. Faites ensuite de votre application principale un simple projet maven. Une fois que cela fonctionne, commencez à ajouter des dépendances simples, puis divisez votre premier module et ainsi de suite.
Maven est un excellent outil, mais il peut également être une super douleur dans le cou, surtout lorsque les choses ne vont pas dans votre sens. Commencer avec le whammy entier lors de votre premier coup est une recette pour un désastre (c'était pour moi!).
Si les choses sont un peu bizarres, vous pouvez toujours utiliser mvn help:effective-pom
commande pour voir ce que Maven a réellement compris.
D'après votre commentaire, je comprends mieux ce que vous voulez réaliser. Dans ce cas, j'opterais pour l'approche des plugins. Créez un projet qui expose l'API des points d'extension où vous souhaitez isoler le travail. Ensuite, vous pouvez l'utiliser comme dépendance dans un nouveau projet qui le mettra en œuvre. Dans votre application principale, ajoutez simplement les dépendances appropriées pour ces implémentations (n'utilisez pas les modules maven cette fois) et vous devriez être prêt à partir. Finalement, le projet d'application principal ne portera presque aucun code source, tout ce qui est fait dans des projets externes et chargé via des dépendances.
Cependant, vous devrez redéployer toute l'application avec cette approche, que le cœur ait changé ou non, car la guerre est construite statiquement à partir des dépendances, changer l'une d'entre elles implique de reconstruire le tout. Cela semble pire qu'il ne l'est réellement. En effet, seuls les nouveaux changements seront réellement construits, le reste sera essentiellement une copie du ou des pots précédents. Mais comme tout est dans le fichier de guerre, il devra être reconstruit et le serveur devra être arrêté et redémarré.
Si vous devez aller plus loin, les choses deviennent un peu plus compliquées, mais pas impossibles. Je vous recommande de regarder OSGI, Apache Felix pourrait vous aider à démarrer, bien qu'il existe également d'autres implémentations. Cela vous permettra de prendre le pot externe et de les transformer en plugins appropriés. Vous gagnerez beaucoup plus de contrôle sur le cycle de vie d'exécution des composants ouvrant la porte aux rechargements et mises à jour dynamiques. Cela nécessitera cependant des modifications majeures de votre cœur, ce qui n'est probablement pas un bon point de départ. Cependant, une fois que vous avez un projet bien séparé et que toutes les parties sont isolées comme vous le souhaitez, cela pourrait être une prochaine étape naturelle si le démarrage et l'arrêt de l'application lors de la mise à jour est un problème majeur.
La différence fondamentale entre les modules et les dépendances est la suivante:
Vous pouvez trouver la Bible ici .
En espérant que ça aide, bonne chance.