AOP dans les applications java

Publié le Mis à jour le

L’AOP – ou POA – est un paradigme de programmation ayant pour but de compléter la programmation orientée objet. L’AOP permet d’implémenter de façon plus propre les problématiques transverses à l’application. En effet, elle permet de factoriser du code dans des greffons, et de venir déployer ces derniers en divers endroits.

De ce fait, ce paradigme permet d’éviter la dispersion du code tout en améliorant sa réutilisabilité.

Les problématiques transverses traitées par l’AOP sont la plupart du temps techniques (l’identification de problématiques transverses fonctionnelles est plus difficile).
L’AOP permet par exemple d’implémenter:

  • la gestion de la sécurité (Acegi Security utilise l’AOP pour gérer la sécurité au niveau objet),
  • le monitoring et le logging (spring 2 fournit un intercepteur utilisant l’api. Jamon permettant le «monitoring» des applications,
  • le debug,
  • la gestion des transactions,
  • la persistence des données,
  • implémentation des patterns de GoF (gain de modularité pour 17 patterns sur 23).

Une api standardisant les fonctionnalités communes à plusieurs tisseurs d’aspects est proposée par l’AOP Alliance .

Lexique

  • Tisseur (weaver) : Outil qui réalise l’intégration d’un ensemble d’aspects à un ensemble de classes. L’opération de tissage peut être effectuée à la compilation (tissage statique) ou à l’exécution (tissage dynamique). Cette opération est réalisée par la majorité des tisseurs java via la modification de Bytecode.
  • Tissage (weaving) : Opération réalisée par un tisseur.
  • Aspect : Entité logicielle définissant des greffons et leurs points d’insertion.
  • Greffon (advice) : Bloc de code destiné à être exécuté au niveau d’un point de coupure avant, après ou autour du point de jonction.
  • Point de coupure (point cut) : Point dans le code où le tisseur vient insérer le greffon.
  • Point de jonction (join point) : Point autour duquel un ou plusieurs aspects peuvent être ajoutés. Différents types de points de jonction:
  • * Méthodes.
  • * Constructeurs.
  • * Exceptions.

Principaux Tisseurs

Il s’agit du premier tisseur AOP pour java par BEA. Les développement se sont arrêtés à la version 2.0 suite à la fusion AspectWerkz/AspectJ dans AspectJ5

Il s’agit de l’outil phare de l’AOP (première version en 1998). Aspect J permet trois mode de déclaration des aspects:

  • *Annotation java 5 (tissage dynamique au chargement)
  • *Extension de langage (tissage statique via le compilateur AJC)
  • *XML (tissage dynamique, au chargement)

Le plugin eclipse AJDT facilite le développement et le debuggage des aspects.

  • Spring AOP : implémentation par défaut de l’AOP fournit par Spring (fonctionnalités limitées). Le tissage est dynamique à l’exécution (possibilité de déploiement à chaud).
  • Jboss AOP : Jboss AOP est intégré à Jboss AS (des modules de Jboss comme par exemple la gestion des transactions sont implémentés à l’aide de l’AOP). Le tissage peut être effectué durant la compilation, au chargement ou lors de l’exécution ( possibilité de déploiement à chaud). Un des avantages de JBoss AOP est la fourniture d’aspects pré-définis, cependant certains ne sont pas exploitable en dehors de JBoss AS.

Implémentation d’un aspect cache avec AspectJ et OSCache

La problématique traitée dans cet exemple est l’ajout d’un mécanisme de cache pour un service donné (dans l’exemple, ajout d’un cache sur la méthode getBook de BookService). L’AOP nous permet l’intégration d’un tel cache sans avoir à modifier le code existant.
Dans l’exemple ci-dessous nous avons choisi d’utiliser AspectJ5 (déclaration des aspects via les annotations java 5) et OSCache.
Le point de jonction sélectionné est la méthode getBook de la classe BookService :

com.cleverage.proto.BookService.getBook(String)

Ainsi chaque appel à la méthode suivante constituera un point de coupure:

Book book = BookService.getInstance().getBook("ISBN 2-2");

Ci-dessous le code source de l’aspect gérant le cache. Ce code est basique (l’aspect peut uniquement être utilisé sur cette méthode…), il serait plus utile de définir un aspect de cache plus générique, pouvant venir se greffer sur différents services stateless.

@Aspect
public class BookCache {
  // nous utilisons la configuration par defaut
  private static final GeneralCacheAdministrator CACHE_ADMIN = new GeneralCacheAdministrator();

  // definition du point de coupe
  @Pointcut("call(* com.cleverage.proto.BookService.getBook(String)) && args(ref)")
  void getBook(String ref) {
    // écriture d'un code advice de type around
    //(besoin d'executer du code avant et après les points de jonction)
  }

  @Around("getBook(ref)")
  public Object getBookFromCache(final ProceedingJoinPoint thisJoinPoint, final String ref) throws Throwable {
    Book book;
    try
    {
      // recuperation de la valeur à partir du cache
      book = (Book) CACHE_ADMIN.getFromCache(ref, 1000);
    }
    // l'entree n'existe pas ou a expiree
    catch (NeedsRefreshException nre) {
      boolean updated = false;
    }  
    try
    {
      // execution du point de jonction
      book = (Book) thisJoinPoint.proceed(new Object[] { ref });
      // stockage de l'entree dans le cache
      CACHE_ADMIN.putInCache(ref, book);
      updated = true;
    }
    finally {
      if (!updated)
      {
        CACHE_ADMIN.cancelUpdate(ref);
      }
    }
    return book;
  }
}

Conclusion

En tant que paradigme de programmation, l’AOP n’est pas destinée seulement à Java, cependant il n’existe pas dans les autres langages des implémentations aussi mature que celles en java :

Du fait de l’amélioration de la qualité et de la modularité du code, l’avenir de l’AOP est prometteur. Cependant, sa démocratisation passera par une standardisation des APIs et la mise à disposition d’un outillage adapté (debug, modélisation, rétro-ingénierie…).


  • Framework

  • Java

  • JEE