Maison > Java > javaDidacticiel > le corps du texte

Indicateurs de fonctionnalités dans Spring Boot à l'aide de la programmation orientée aspect

DDD
Libérer: 2024-10-21 06:15:02
original
808 Les gens l'ont consulté

Feature Flags in Spring Boot using Aspect-Oriented Programming

Dans le développement de logiciels modernes, les indicateurs de fonctionnalités jouent un rôle crucial dans la gestion des versions de fonctionnalités. En utilisant des indicateurs de fonctionnalités (également appelés bascules de fonctionnalités), les développeurs peuvent activer ou désactiver des fonctionnalités de manière dynamique sans redéployer l'application. Cette approche permet des versions incrémentielles, une expérimentation contrôlée et des déploiements plus fluides, en particulier dans les systèmes complexes et à grande échelle.

Dans ce blog, nous explorerons comment implémenter des indicateurs de fonctionnalités dans une application Spring Boot à l'aide de la programmation orientée aspect (AOP). AOP nous permet de modulariser des préoccupations transversales telles que la journalisation, la sécurité et le basculement de fonctionnalités, en les séparant de la logique métier principale. En tirant parti d'AOP, nous pouvons concevoir une implémentation d'indicateurs de fonctionnalités flexible et réutilisable qui peut s'adapter à diverses exigences.

Nous montrerons comment AOP peut intercepter les appels de méthode, vérifier les indicateurs de fonctionnalités et exécuter conditionnellement des fonctionnalités en fonction de l'état de l'indicateur. Cela rend l'implémentation plus propre, plus maintenable et plus facile à modifier. Il est recommandé de suivre une compréhension de base d'AOP, de Spring Boot et des indicateurs de fonctionnalités.

Vous pouvez trouver le code référencé dans cet article ici : Feature Flags with Spring Boot.

Configuration des classes de base des indicateurs de fonctionnalité

  • En supposant que vous ayez déjà configuré un projet Spring Boot, la première étape consiste à définir une interface FeatureFlagValidator. Cette interface sera chargée d'encapsuler la logique qui valide si une fonctionnalité doit être activée ou désactivée en fonction de conditions personnalisées.
public interface FeatureFlagValidator {
  boolean validate(Object... args);
}
Copier après la connexion
Copier après la connexion
Copier après la connexion

La méthode validate prend en compte un nombre variable d'arguments (Object... args), ce qui donne la flexibilité de transmettre tous les paramètres nécessaires à la logique de validation. La méthode retournera true si la fonctionnalité doit être activée, ou false si elle doit rester désactivée. Cette conception permet une logique de validation des indicateurs de fonctionnalité réutilisable et facilement configurable.

  • Maintenant, une fois que notre interface de validation est prête, la prochaine étape consistera à créer une annotation FeatureFlag personnalisée. Cette annotation sera appliquée aux méthodes qui doivent être activées ou désactivées en fonction de conditions spécifiques.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FeatureFlag {
  Class<? extends FeatureFlagValidator>[] validators();
}
Copier après la connexion
Copier après la connexion
Copier après la connexion

Cette annotation accepte un tableau de classes FeatureFlagValidator, permettant une logique configurable pour déterminer si une fonctionnalité doit être activée ou désactivée.

  • Après cela, nous allons enfin créer notre aspect. Cette classe d'aspect gérera la validation des indicateurs de fonctionnalité en fonction de l'annotation FeatureFlag.
@Aspect
@Component
public class FeatureFlagAspect {
  @Autowired private ApplicationContext applicationContext;

  @Around(value = "@annotation(featureFlag)", argNames = "featureFlag")
  public Object checkFeatureFlag(ProceedingJoinPoint joinPoint, FeatureFlag featureFlag)
      throws Throwable {
    Object[] args = joinPoint.getArgs();
    for (Class<? extends FeatureFlagValidator> validatorClass : featureFlag.validators()) {
      FeatureFlagValidator validator = applicationContext.getBean(validatorClass);
      if (!validator.validate(args)) {
        throw new RuntimeException(ErrorConstants.FEATURE_NOT_ENABLED.getMessage());
      }
    }
    return joinPoint.proceed();
  }
}
Copier après la connexion
Copier après la connexion
Copier après la connexion

Cette classe comprend une méthode qui

  • intercepte les appels aux méthodes annotées avec @FeatureFlag, valide l'indicateur de fonctionnalité à l'aide du
  • fournit des validateurs et lève une GenericException si la validation échoue.

Création et configuration des classes Feature Flags

  • Disons que nous voulons gérer une Fonctionnalité A à l'aide d'un indicateur de fonctionnalité. Pour ce faire, nous devons implémenter l'interface FeatureFlagValidator et l'appliquer en utilisant l'annotation FeatureFlag autour des méthodes pertinentes.
public interface FeatureFlagValidator {
  boolean validate(Object... args);
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
  • FeatureAFeatureFlag : Cette classe implémente l'interface FeatureFlagValidator. Il contient une logique qui vérifie si la Fonction A est activée ou désactivée en faisant référence à une classe de configuration (FeatureFlagConfigs). Si la fonctionnalité est désactivée, un message d'avertissement est enregistré, ce qui facilite la surveillance et le débogage.
  • Maintenant, vous devez vous demander quelle est cette classe FeatureFlagConfigs dans le code ci-dessus. La classe FeatureFlagConfigs est responsable de la gestion des indicateurs de fonctionnalités via le fichier de configuration (tel que application.properties). Cette classe lie les valeurs des indicateurs de fonctionnalités de la configuration, vous permettant de contrôler quelles fonctionnalités sont activées ou désactivées au moment de l'exécution.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FeatureFlag {
  Class<? extends FeatureFlagValidator>[] validators();
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
  • Exemple de configuration (application.properties) : Vous pouvez contrôler l'état de la Fonction A en ajoutant une propriété dans votre fichier de configuration. Par exemple, définir feature-flags.feature-a-enabled=true activera la fonctionnalité. Cela simplifie le basculement entre les fonctionnalités sans redéployer ni modifier la base de code.
@Aspect
@Component
public class FeatureFlagAspect {
  @Autowired private ApplicationContext applicationContext;

  @Around(value = "@annotation(featureFlag)", argNames = "featureFlag")
  public Object checkFeatureFlag(ProceedingJoinPoint joinPoint, FeatureFlag featureFlag)
      throws Throwable {
    Object[] args = joinPoint.getArgs();
    for (Class<? extends FeatureFlagValidator> validatorClass : featureFlag.validators()) {
      FeatureFlagValidator validator = applicationContext.getBean(validatorClass);
      if (!validator.validate(args)) {
        throw new RuntimeException(ErrorConstants.FEATURE_NOT_ENABLED.getMessage());
      }
    }
    return joinPoint.proceed();
  }
}
Copier après la connexion
Copier après la connexion
Copier après la connexion

Utilisation des indicateurs de fonctionnalités

  • Maintenant, disons que nous avons un DemoService dans lequel nous souhaitons utiliser le FeatureAFeatureFlag que nous venons de créer. Nous l'utiliserons ainsi :
@Component
@RequiredArgsConstructor
public class FeatureAFeatureFlag implements FeatureFlagValidator {
  private final FeatureFlagConfigs featureFlagConfigs;
  private final Logger logger = LoggerFactory.getLogger(FeatureAFeatureFlag.class);

  @Override
  public boolean validate(Object... args) {
    boolean result = featureFlagConfigs.getFeatureAEnabled();
    if (!result) {
      logger.error("Feature A is not enabled!");
    }
    return result;
  }
}
Copier après la connexion
Copier après la connexion

Depuis, nous avons annoté notre méthode avec l'annotation FeatureFlag et utilisé la classe FeatureAFeatureFlag, donc avant d'exécuter la méthode featureA, FeatureAFeatureFlag sera exécuté et il vérifiera si la fonctionnalité est activée ou non.

Note:

Notez ici que le champ des validateurs est un tableau dans l'annotation FeatureFlag, nous pouvons donc lui transmettre plusieurs validateurs.

Utilisation des indicateurs de fonctionnalités dans le contrôleur

  • Dans l'exemple précédent, nous avons appliqué le FeatureAFeatureFlag autour d'une méthode de couche de service. Cependant, les indicateurs de fonctionnalités peuvent également être appliqués aux méthodes du contrôleur. Cela nous permet d'inspecter les paramètres d'entrée et, en fonction de conditions spécifiques, de contrôler si l'utilisateur peut poursuivre le flux demandé.
  • Considérons une fonctionnalité B, qui a une méthode de contrôleur acceptant un paramètre de requête flowType. Actuellement, la fonctionnalité B ne prend en charge que le flux INWARD, tandis que d'autres flux sont en cours de test pour un déploiement futur. Dans ce cas, nous allons créer un indicateur de fonctionnalité pour la fonctionnalité B qui vérifie si le flowType est INWARD et garantit que seul ce flux est autorisé pour le moment.

Pour implémenter l'indicateur de fonctionnalité pour la fonctionnalité B, nous devrons mettre à jour les fichiers FeatureFlagConfigs et application.properties en conséquence.

public interface FeatureFlagValidator {
  boolean validate(Object... args);
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FeatureFlag {
  Class<? extends FeatureFlagValidator>[] validators();
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
  • Maintenant, nous allons créer une classe FeatureBFeatureFlag. La classe FeatureBFeatureFlag validera si la fonctionnalité B est activée et si le flowType correspond à la valeur autorisée (INWARD). Si ces conditions ne sont pas remplies, la fonctionnalité sera désactivée.
@Aspect
@Component
public class FeatureFlagAspect {
  @Autowired private ApplicationContext applicationContext;

  @Around(value = "@annotation(featureFlag)", argNames = "featureFlag")
  public Object checkFeatureFlag(ProceedingJoinPoint joinPoint, FeatureFlag featureFlag)
      throws Throwable {
    Object[] args = joinPoint.getArgs();
    for (Class<? extends FeatureFlagValidator> validatorClass : featureFlag.validators()) {
      FeatureFlagValidator validator = applicationContext.getBean(validatorClass);
      if (!validator.validate(args)) {
        throw new RuntimeException(ErrorConstants.FEATURE_NOT_ENABLED.getMessage());
      }
    }
    return joinPoint.proceed();
  }
}
Copier après la connexion
Copier après la connexion
Copier après la connexion

Nous utiliserons l'indicateur de fonctionnalité ci-dessus avec le contrôleur comme ceci :

@Component
@RequiredArgsConstructor
public class FeatureAFeatureFlag implements FeatureFlagValidator {
  private final FeatureFlagConfigs featureFlagConfigs;
  private final Logger logger = LoggerFactory.getLogger(FeatureAFeatureFlag.class);

  @Override
  public boolean validate(Object... args) {
    boolean result = featureFlagConfigs.getFeatureAEnabled();
    if (!result) {
      logger.error("Feature A is not enabled!");
    }
    return result;
  }
}
Copier après la connexion
Copier après la connexion

De cette façon, nous pouvons créer nos indicateurs de fonctionnalités personnalisés dans Spring Boot. Nous avons créé des indicateurs de fonctionnalités de manière à pouvoir les étendre et nous pouvons ajouter plusieurs façons de basculer entre les fonctionnalités. L'approche ci-dessus peut également être modifiée et à l'intérieur des validateurs d'indicateurs de fonctionnalités, nous pouvons également utiliser une table de base de données pour basculer les fonctionnalités. Ce tableau peut être géré à l'aide d'un panneau d'administration.

Si vous êtes arrivé jusqu’ici, je vous remercie de tout cœur pour votre temps. J'espère que vous avez trouvé cet article qui valait l'investissement. Vos commentaires sont très appréciés. Merci! Bon apprentissage !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!