Theodo France

Theodo France

IT / Digital, Logiciels

Paris, Casablanca, London, Lyon, Nantes

Explorez leurs posts

Parcourez les posts publiés par l’entreprise pour une immersion dans leur culture et leurs domaines d’expertise.

Theodo Named 2025 Google Cloud Services Partner of the Year

Las Vegas, April 8, 2025 Theodo today announced that it has received the 2025 Google Cloud Services Partner of the Year. Theodo is being recognized for its achievements in the Goog…

04/07/2025

REX après la migration d’une feature Android/iOS vers KMP

Dans un premier article, nous avons exploré comment migrer progressivement une application native Android/iOS vers Kotlin Multiplatform (KMP). Si vous avez suivi ce guide, vous ave…

04/07/2025

ShedLock : Gérer efficacement les tâches planifiées dans une architecture multi-instances

Introduction Pour les applications d'entreprise, en 2025 l’exécution de tâches planifiées est un besoin courant : génération de rapports, traitements par lots, synchronisation de d…

04/07/2025

Comment diviser par 2 votre temps de CI grâce à ces simples astuces

Chez Theodo HealthTech, notre politique est de créer un code de qualité tout en respectant nos délais de livraison. Cependant, pendant trois sprints consécutifs, nous avons livré d…

08/04/2025

How QRQC helps me better manage bugs on my project?

As a software developer, you spend most of your time delivering code and then fixing bugs you introduced in your code. The Pareto principle is a great way to represent our day-to-d…

04/07/2025

How we migrated from AWS Glue to Snowflake and dbt

Today, I’ll tell you about our ETL migration from AWS Glue to the Snowflake and dbt modern data stack. My team’s mission is to centralize and ensure data reliability from multiple…

04/07/2025

Sécuriser les partages Notion : guide pour tous

Chez Theodo Fintech, nous avons fait de Notion notre QG digital. Documentation produit, projets tech, comptes rendus, référentiels clients ou financiers… tout y passe. Et c’est bie…

04/07/2025

Construire un produit Gen AI : le guide de survie pour les PMs

Bienvenue dans l'ère de l'IA générative, où les machines créent du contenu de manière autonome. Pour les product managers (PMs), cela représente une révolution autant qu'un défi. L…

08/04/2025

Qu’est-ce que le scaling ?

Une bonne application est une application qui tient sa charge d’utilisateurs, notamment grâce à un scaling controlé. Dans cet article nous aborderons ce sujet, et plus particulière…

04/07/2025

How LLM Monitoring builds the future of GenAI ?

Discover how Langfuse offers secure, open-source monitoring for LLM and GenAI solutions. Large Language Models (LLMs) are popping up everywhere and are more accessible than ever. W…

04/07/2025

Les annotations java custom pour respecter l’architecture hexagonale

Le problème que l’on veut résoudre Lorsque l’on développe une API avec Spring Boot, il est fréquent d’utiliser les annotations fournies par le framework, telles que @Service, @Comp…

04/07/2025

Le kit de survie du Product Manager responsable en 4 étapes

Alors que j’étais tranquillement en train de me laisser charmer par la dégustation gratuite de tofu fumé de mon Biocoop l’année dernière, une soudaine prise de conscience a heurté…

08/04/2025

Faites des Plugins pas la Guerre: REX sur ma bataille pour écrire un plugin

Imaginez commencer chaque projet avec tous les outils configurés et prêts à l’emploi. Le rêve, non ? En tant que développeur Android, j’ai toujours eu à portée de main les outils n…

04/07/2025

Don’t use Langchain anymore : Atomic Agents is the new paradigm !

Introduction Since the rise of LLMs, numerous libraries have emerged to simplify their integration into applications. Among them, LangChain quickly established itself as the go-to…

04/07/2025

Optimize Your Google Cloud Platform Costs with Physical Bytes Storage Billing

In today's data-driven world, cloud providers are essential for efficiently managing, processing, and analyzing vast amounts of data. When choosing one such provider, Google Cloud…

08/04/2025

Tech Radar Cloud

Ce Tech radar regroupe une cinquantaine de technologies Cloud et DevOps éprouvées par les experts de Theodo Cloud durant plus de 4 ans de projets. Téléchargez le 2ème volume de not…

08/04/2025

Les annotations java custom pour respecter l’architecture hexagonale

Theodo France

Les annotations java custom pour respecter l’architecture hexagonale

Le problème que l’on veut résoudre

Lorsque l’on développe une API avec Spring Boot, il est fréquent d’utiliser les annotations fournies par le framework, telles que @Service, @Component ou @Repository pour réaliser nos injections de dépendances. Si cette approche fonctionne parfaitement dans le cadre d’architecture plus “traditionnelles”, elle peut poser problème dans le cadre de l’implémentation d’une architecture hexagonale.

Capture d’écran 2025-07-04 à 10.12.05.png

Contexte : développer une API avec l’architecture hexagonale

L’architecture hexagonale repose sur un principe central : l’indépendance du domaine. Cela signifie que la partie “métier” (ou Domain) de notre application doit se prémunir de toute dépendance envers des frameworks externes comme Spring Boot, Hibernate ou tout autre implémentation technique. Pourquoi ? Car le domaine représente la logique fondamentale de notre application, qui doit pouvoir évoluer indépendamment des différents outils ou infrastructure que l’on utilise.

En quoi cela peut être utile ?

  • Nous pouvons commencer à développer le domaine avant d’acter sur nos choix techniques.

  • Il est bien plus facile de tester le domaine sans se soucier du framework choisi.

💡 Pour celles et ceux qui ne seraient pas familier avec les concepts d’architecture hexagonale et de Domain-Driven-Design, je vous mets ici quelques ressources qui pourraient vous intéresser :

Le couplage avec Spring Boot : comprendre les implications

L'utilisation des annotations Spring Boot comme @Service ou @Component dans notre domaine métier crée un couplage technique qu'il convient d'examiner attentivement. Cette dépendance a des implications importantes :

  • Elle lie notre logique métier à un framework spécifique, ce qui peut compliquer les migrations futures.

  • Elle peut rendre plus difficile l'extraction ou la réutilisation du code métier dans d'autres contextes.

  • Sur des applications destinées à durer dans le temps, ce couplage risque de transformer notre code en legacy difficile à faire évoluer pour les équipes futures.

Cependant, l'utilisation des annotations Spring présente aussi des avantages immédiats en termes de simplicité et de conventions établies.

Face à cette situation, deux approches s'offrent à nous :

  1. Accepter ce couplage si nous sommes certains que notre application restera toujours liée à Spring Boot.

  2. Rechercher des alternatives permettant d'isoler notre domaine métier du framework technique.

Ce choix dépend de la question fondamentale : "Est-ce que j'accepte que mes règles métier dépendent d'un framework technique ?"

Si votre réponse est non, il existe des solutions élégantes pour éviter ce couplage, et c'est justement l'objet de cet article : vous présenter une approche alternative utilisant des annotations personnalisées en Java standard plutôt que des annotations spécifiques à Spring Boot.

Défi : réaliser les injections de dépendances sans dépendre de Spring Boot

Une des fonctionnalités majeures de Spring Boot est la gestion automatique des injections de dépendances via son conteneur IoC. Si nous ne voulons pas que le domaine soit lié à Spring, comment pouvons nous quand même bénéficier de ces injections “automatique” ? Trois solutions s’offrent à nous :

  1. Faire les injections “à la main” via des classes de configuration et en définissant les beans nécessaires.

  2. Identifier les classes du domaine à intégrer au conteneur IoC via le nom de classe.

  3. Utiliser des annotations java custom pour indiquer à Spring Boot quelles classes du domaine doivent être intégrées au conteneur IoC (cette méthode est semblable à la précédente mais elle est un poil plus robuste car elle ne dépend pas du nommage de nos classes).

Dans la suite de cet article, nous allons passer rapidement sur la première méthode et ses limites. Nous verrons ensuite l’implémentation de la troisième méthode qui va s’avérer bien plus simple et scalable. 🙂

L’injection de @Bean à la main

Considérons un cas concret dans lequel nous avons un usecase de notre domaine, DepositMoneyUseCase, qui dépend d’un port nommé WalletRepositoryPort. Voici comment nous pourrions configurer cette dépendance dans une classe dédiée :

Capture d’écran 2025-07-04 à 10.12.37.png

  • Nous utilisons ici @Configuration et @Bean pour indiquer à Spring de gérer manuellement l’injection de WalletRepositoryPort dans le constructeur de DepositMoneyUseCase

  • Cette approche fonctionne très bien, car elle respecte l’indépendance du domaine. Aucun dépendance à Spring n’est introduite dans notre domaine comme nous pouvons le voir dans le bout de code suivant.

Capture d’écran 2025-07-04 à 10.12.58.png

🚫 Les limites de cette méthode

Imaginons que nous ajoutons plusieurs nouveaux usecases ou ports à notre domaine. Chaque nouvelle classe ou dépendance nécessite une mise à jour manuelle de la configuration. Cela devient vite fastidieux, surtout dans des projets de grande envergure avec beaucoup de logique métier.

Capture d’écran 2025-07-04 à 10.13.20.png

Bien que l’injection manuelle respecte les principes de l’architecture hexagonale, elle peut rapidement devenir un goulot d’étranglement en termes de productivité. Pour éviter ces inconvénients, une alternatives plus élégante consiste à utiliser des annotations custom, qui permettent de simplifier et d’automatiser la déclaration des beans tout en maintenant l’indépendance du domaine.

C’est la solution que je vais vous présenter dans la section qui suit 🙂.

L’utilisation d’annotation custom

Principe

L’idée centrale est de créer une annotation, par exemple @DomainUseCase, pour marquer les classes du domaine que Spring Boot doit gérer. Plutôt que d’annoter directement nos classes avec @Service ou @Component (ce qui introduirait une dépendance à Spring Boot), nous utilisons notre propre annotation, spécifique à notre projet.

Ensuite, une configuration Spring est utilisée pour :

  1. Scanner les classes annotées avec @DomainUseCase.

  2. Enregistrer automatiquement ces classes comme beans dans conteneur IoC de Spring.

Maintenant, transformons notre précédent exemple pour mettre en place cette méthode. Tout d’abord, nous allons “décorer” notre usecase métier avec notre nouvelle annotation custom :

Capture d’écran 2025-07-04 à 10.13.48.png

Cette nouvelle annotation est créée dans le domaine et est définie comme suit :

Capture d’écran 2025-07-04 à 10.14.10.png

Il nous reste à indiquer à Spring que les classes décorées par notre nouvelle annotation doivent être scannées pour qu’il les intègre dans son conteneur IoC, et ça se passe dans notre fameuse classe de configuration.

Capture d’écran 2025-07-04 à 10.14.36.png

  • @ComponentScan :

    • Scanne le package "io.dfrances.multi.module.hexagonal.api.domain" pour y trouver des classes.

    • Applique un filtre spécifique pour inclure uniquement les classes annotées avec @DomainUseCase.

  • Filtre personnalisé :

    • type = FilterType.ANNOTATION indique que Spring doit chercher des annotations spécifiques.

    • classes = DomainUseCase.class précise notre annotation cible.

Les points forts de cette méthode :

🤖 Automatisation complète

Contrairement à l’injection manuelle, où chaque nouveau usecase doit être ajouté explicitement dans une classe de configuration, cette méthode détecte automatiquement les classes annotées @DomainUseCase. Ainsi, l’ajout d’un nouveau usecase se résume à :

  1. Écrire la classe.

  2. L’annoter de @DomainUseCase

Spring s’occupe du reste.

📏 En quoi est-ce que cela s’aligne avec l’architecture hexagonale ?

Cette méthode fait écho au principe d’inversion de dépendance :

  • Ce n’est plus le domaine qui dépend du framework (Spring Boot en l’occurence).

  • C’est Spring Boot qui s’adapte au domaine en identifiant les classes nécessaires grâce à l’annotation @DomainUseCase

Petit bonus : Documentation pour les développeurs

L’utilisation d’annotation custom, comme notre @DomainUseCase, peut améliorer la lisibilité du code et faciliter l’onboarding de nouveaux développeurs qui ne serait pas sensibiliser aux principes de l’architecture hexagonale.

Capture d’écran 2025-07-04 à 10.15.13.png

Pour celles et ceux utilisant IntelliJ IDEA (je ne sais pas pour les autres), nous pouvons même mettre en forme cette documentation directement depuis l’IDE 🙂

Capture d’écran 2025-07-04 à 10.15.37.png

NB : depuis Java 23 il est possible d’utiliser MarkDown pour formater la Javadoc (https://openjdk.org/jeps/467)

Conclusion

L’indépendance du domaine est un pilier fondamental de l’architecture hexagonale. En veillant à ce que notre logique métier ne soit pas dépendante d’un framework technique comme Spring Boot, nous rendons notre application plus testable et robuste au changement. J’entends déjà certains détracteurs me susurrer à l’oreille que ne pas utiliser les annotations Spring dans le domaine est quelque chose d’overkill. Comme nous l’avons vu à travers cet article, créer une annotation custom que l’on pourra réutiliser à de nombreux endroits de notre domaine n’est pas beaucoup plus coûteux !

Cela dit, tout dépend du contexte de notre projet. Si ce genre de concept nous semble inutilement complexe ou peu adapté, rien ne nous empêche de prendre certains concepts de l’architecture hexagonale et d’en délaisser certains. À vous de voir. 😉

BONUS : Que vaut le coup de migration si je veux migrer sur Quarkus (par exemple) ?

Quarkus repose sur l’extension Arc (CDI), et ne supporte ni @ComponentScan, ni @Configuration.

À la place, il détecte automatiquement les beans à condition qu’ils soient dans le classpath de compilation et annotés avec des annotations CDI (@Singleton, @ApplicationScoped, etc.).

Si l’on veut continuer à utiliser @DomainUseCase comme repère, nous pouvons la transformer en @Stereotype CDI :

Capture d’écran 2025-07-04 à 10.16.01.png

De cette manière, nous pouvons retirer la classe de Configuration. Nous perdons, certes, l’indépendance du domaine car notre annotation est maintenant décorée de @Stereotype et @ApplicationScoped mais autrement, nous avons littéralement copié-collé notre domaine d’un projet à l’autre avec un coup de migration assez faible.

Article rédigé par Dorian Frances