# Tissage dans la programmation orientée aspect

Le tissage est l'étape de la programmation orientée aspect qui a pour but d'insérer des bouts de codes appelés greffons (Advice) dans le code métier d'une application. Tisser un greffon dans une méthode revient à redéfinir la méthode comme la composition de son corps avec le greffon. Le tissage d'aspects au niveau de l'application est un mécanisme offrant l'extensibilité et l'adaptabilité, permettant ainsi à l'application de s'adapter facilement quand des nouveaux besoins font surface.
Tisser un aspect peut se faire à plusieurs moments : à la compilation, au chargement et à l'exécution. Il existe de nombreux tisseurs dans différents langages mais c'est en Java que l'on trouve les tisseurs les plus matures (utilisabilité, stabilité, performances, intégration aux outils...).

## Définitions & Rappels
### Aspect

    Un aspect est une entité logicielle qui capture une fonctionnalité transversale à une application. C'est généralement un ensemble de greffons et de points de coupe d'un logiciel.

### Greffon (advice)

    C'est un bloc de code définissant le comportement d'un aspect. Ce bloc de code est destiné à être exécuté au niveau d’un point de coupe avant, après ou autour du point de jonction.

### Point coupe

    Une coupe (pointcut) désigne un ensemble de points de jonction.

### Point de jonction

    Un point de jonction(join point) est un point dans l'exécution du programme où un ou plusieurs aspects peuvent être ajoutés.Endroit où des aspects peuvent être ajoutés (Méthode, constructeur, Exceptions...)

### Join point shadows

    est la projection statique d'un point de jonction, sur le code du programme.

### Déclaration inter-type

    C'est moyen par lequel un aspect ajoute des informations comme des nouvelles propriétés, des nouvelles méthodes ou des interfaces à une classe existante, permettant ainsi d'étendre cette dernière.

### Le tissage statique

    s'effectue à la compilation ou au chargement. Une fois un aspect tissé, il est impossible de le retirer. Lors ce tissage, le code aspect est fusionné avec le code métier$^,$:
* soit pour donner un nouveau code source.
* soit pour donner un pseudo-code intermédiaire.

### Le tissage dynamique

    permet de garder les aspects et le code applicatif complètement séparés. Ainsi, l'exécution, les aspects peuvent être tissés, donc ajoutés au code ou retirés. Cela accroît l’intérêt porté sur la POA pour le prototypage et le test rapides, car on n'a plus besoin de ré-compiler, redéployer et relancer l'application.

## Tissage

Le tissage classique basé sur les ombres de point de jointures (join point shadows) comme emplacement de tissage a un problème:efficacité de compilation. Le tissage basé sur les enveloppes vise à diminuer le nombre des emplacements de tissage et par conséquent, la surcharge du au tissage, en introduisant des accesseurs(getter et setter) pour les champs et des proxys pour les méthodes de classes. L'intérêt de cette technique est à trois niveaux. Premièrement, la simplification de la recherche des emplacements de tissage, ceux-ci sont placés dans les enveloppes. Deuxièmement, la diminution du nombre des actions de tissage, car un aspect est tissé une seule fois par champs affecté et troisièmement, simplification du processus de tissage, car on ne se préoccupe plus de maintenir le contrôle de structure des méthodes affectées par le tissage. Grâce à la compilation à temps (just in time), l’indirection introduite par cette technique à un impact faible sur la performance lors de l'exécution. Elle est un complément au tissage statique classique et bien adaptée pour la phase “compilation-teste-debogage”.

### Tissage à la compilation

Le tissage à la compilation est le plus simple. Il consiste, à prendre le code applicatif et les aspects en entrée et de produire un code mélangé apportant les nouvelles fonctionnalités. Pour ce faire, une étape de pré compilation est nécessaire ou alors, un tisseur est couplé au compilateur. Cette approche produit un code qui demandera moins de contrôles à l'exécution du fait du travail accompli par le compilateur. Ce tissage est obligatoire si les aspects ajoutent des informations nécessaire à la compilation des classes comme de nouveaux champs ou nouvelles méthodes.

### Tissage au chargement

Ajouter des nouvelles fonctionnalités aux composants existants sous format binaire se fait par instrumentation du code. Ainsi le tissage se fait au moment où le chargeur de classes charge le code dans la machine virtuel Java (JVM).

### Tissage à l'exécution

Cette approche permet de changer le comportement du programme à l'exécution. Pour y parvenir, le support de tissage et d'exécution des aspects est placé directement dans l’environnement d'exécution. L'environnement d'exécution, comme la JVM adapté aspects, fournit une interface pour le tissage des aspects pendant l'exécution permettant de changer le modèle d'exécution d'une application.

## Tisseurs

Un élément central de la POA est le tisseur. Étant donné un ensemble de programmes ciblés et un ensemble d'aspects définis, le tisseur transforme le programme cible à tisser en un programme enrichi par ces aspects selon certaines contraintes. Il existe plusieurs tisseurs en java. Nous allons considérer ici, les tisseurs les plus connus.

### AspectJ

AspectJ est le framework orienté aspect le plus connu. Son mode tissage était purement statique avant sa fusion avec AspectWerkz$^,$en décembre 2005. Cette fusion a permis à AspectJ de faire du tissage dynamique, mais au chargement seulement, et de se doter des annotions dans la mise en œuvre des aspects.
À la compilation, le compilateur AspectJ appelé ajc prend en entrée le code aspect et le code métier et produit en sortie un byte-code tissé. Il est aussi capable de faire de la post-compilation en tissant des aspects dans les fichiers de classe compilés ou dans les fichiers JAR. Ce compilateur est divisé en deux parties, une partie front-end et une back-end. Le front-end, est cette partie qui reçoit en entrée le code aspects et le code métier et qui produit un byte-code annoté avec les informations représentants tout ce qui n'est pas du java pur comme les greffons et les points de coupe. Le back-end quant à lui prend ce byte code annoté et implémente les transformations basées sur ces informations et produit les fichiers de classes tissés. Ces transformations consistent à instrumenter le code en insérant les appels aux méthodes de greffons déjà précompilés.
Pour faire le tissage au chargement, AspectJ utilise un agent de chargement et une configuration fourni sous fichier xml. Cet agent est un chargeur de classe spécial permet d'intervenir au niveau du byte-code. L'agent enrichit donc le code de la classe avec le code d'aspects, pendant le chargement de la classe dans la JVM.

### JBoss

JBoss offre un service, nommé JBoss AOP, afin d'utiliser les concepts de l'AOP. C'est une équipe dirigé par Bill Bruke qui est à l'origine du framework, ces droits furent rachetés en 2004 par Red Hat. Avec Jboss AOP il y a deux façons de créer des greffons
* en utilisant un ensemble d'aspect prédéfinis, mais certains ne peuvent d'être utilisé qu'avec JBoss Application Server.
* en les créant.
Les aspects avec JBoss AOP, sont écrits en Java pur sans extension syntaxique mais nécessite l'utilisation d'une API propre à JBoss AOP. Un aspect se compose obligatoirement de deux fichiers :
* le premier contient le code du greffon, appelé intercepteur en JBoss
* le deuxième est un fichier xml. Ce fichier permet de configurer les coupes et d'assurer le déploiement à chaud des aspects au cours de l'exécution.
Avec JBoss AOP le tissage peut être :
* statique : pour cela il faut déclarer lier l'intercepteur et le point de jonction en utilisant la balise <bind>
* dynamique : en utilisant la balise <prepare> mais avant cela il faut configurer la Machine Virtuelle Java pour supporter l'échange à chaud(HotSwapping). L'activation du HotSwap permet d'instrumenter le bytecode des intercepteurs durant l'exécution.

### Spring

Spring propose un framework, nommé Spring AOP, permettant d'utiliser les concepts de la POA. Cependant, le support de la POA proposé par Spring est plus limité que celui d’AspectJ en termes de points de jonction pour définir les coupes, mais Spring à la capacité d'utiliser les aspects développé en AspectJ.
Avec Spring, les greffons sont implémentés sous forme d'une classe java implémentant une certaine interface, selon le type de greffon voulu, sa déclaration se fait à l'aide d'un bean dans le fichier de configuration. Dans ce fichier il faut déclarer également un bean pour spécifier le point de coupe et un autre pour lier le greffon au point de coupe. La portée des aspects est limitée avec Spring, seules les classes définies sous forme de bean peuvent être interceptées.
Il existe trois façons pour définir un point de coupe en Spring AOP:
* avec le nom des méthodes à intercepter.
* avec des expressions régulières pour désigner les méthodes à intercepter.
* avec AspectJ.
Avec Spring AOP, de base les aspects sont tissés au chargement qui se réfère au processus de tissage d'AspectJ, le tissage s'effectue à l'aide de la création dynamique de proxy pour les beans dont les méthodes doivent être interceptées. La génération de ces proxy se fait dans le fichier de configuration. Mais on peut également modifier les greffons pendant l'exécution du programme en paramétrant le fichier de configuration.

### JAC

JAC$^,$ (Java Aspect Components) est un framework de POA et non un nouveau langage dans lequel la notion de centrale est le composant aspect. Il offre deux niveaux de POA permettant soit de programmer totalement de nouveaux aspects soit de configurer les aspects préprogrammés pour les adapter aux besoins. Un point de coupe est composé de quatre expressions de correspondance à savoir objets, classes, méthodes et hébergeurs. Pour développer un composant aspect, il faut définir des points de coupe et les associer aux méthodes d’encapsulations définies dans les classes adaptateurs Wrapper.
Avec JAC on peut aussi configurer les aspects, en associant à chaque composant aspect un fichier texte décrivant le configuration. Pour effectuer le tissage à l'exécution, le tisseur doit faire une réflexion sur le code métier pour décider si une méthode ou une propriété doit être encapsulé ou pas. Ces décisions sont prises en se basant sur les définitions des points de coupe. Pour y parvenir, un ensemble d’informations sur le code métier sont sauvegardées en mémoire et construites lors du chargement de l’application. Les adaptateurs dynamiques reposent sur le Protocole à méta-objets, permettant d’insérer des crochets dans les adaptateurs lors du chargement. Ces crochets sont des invocations de réflexion qui permettent à la méthode encapsulée être résolue lors de l'exécution. Ainsi un API permettant d’avoir des informations de type à l'exécution peut les accéder.
Contrairement à AspectJ qui traite les aspects au niveau des classes, les instances d'une même classe dans JAC peuvent être modifiées différemment. Grâce aux quatre expressions composant le point de coupe, la granularité est au niveau de l'objet.

## Comparaison

Nous allons comparer les tisseurs vus ci-haut, en fonction de leur mise œuvre des aspects. Nous verrons la syntaxe, les points de coupe et les primitives associées et en fin, nous considérons leurs types de tissage et les fonctionnalités offertes.

### Syntaxe des aspects

La syntaxe est l'un des critères qui nous permet d'établir les différences et les similarités entre ces différents environnements. Avant de tisser ces aspects, il faut d'abord les écrire.
Comparaison sur la syntaxe des aspects :
| | Déclaration Aspect | Déclaration Inter-type | Greffon | Point de coupe | Configuration |
| AspectJ | code aspectJ, annotation, ou XML | code aspectJ, annotation, ou XML | code aspectJ, annotation | code aspectJ, annotation | aop.xml |
| JAC | code java | code java | code java | code java | fichier texte .acc |
| JBossAOP | code java + XML | annotation ou XML | code java | statique(fichier XML) ou dynamique (API) | jboss-aop.xml |
| SpringAOP | code java + XML | Donnée | Donnée | Donnée | springconfig.xml |
Il convient de noter qu'AspectJ utilise le fichier XML seulement pour le faire le tissage au chargement. JAC de son côté utilise un fichier texte .acc par classe pour effecteur

### Points de coupe, points de jonction et primitives associées

Les points de coupe sont très importants pour l'étape de tissage, car ils définissent les endroits dans le code métiers où il faut insérer du code aspects. Les points de jonction représentent les endroits exacts dans le flux d'exécution où le greffon est appelé. Les tisseurs fournissent différentes primitives pour faire des correspondances(matching).
* initialisation : points à l'initialisation des classes et des objets
* invocation : points où les méthodes et autres éléments de code sont appelés ou exécutés
* gestions des exceptions : points où les exceptions et les erreurs sont manipulées
Comparaison sur les points de coupe et primitives associées :
| | Points de jonction | Points de jonction | Points de jonction | Points de jonction | Points de coupe | Points de coupe | Points de coupe | Points de coupe |
| | Initialisation | Invocation | Gestion des exceptions | Contrôle du flux | Matching de point de coupe | Composition de point de coupe | Forme des greffons | Contexte dynamique |
| AspectJ | instanciation, statique, préinitialisation | {méthode, constructeur, greffon} x {appel, exécution} | gestionnaire (handler) | cflow, cflowbelow | signature, type de pattern, sous-type, joker, annotation | &&, !,|| | before, after, after running, after throwing, around | this, target, args, |
| JAC | instanciation | exécution des méthodes, exécution des constructeurs | gestionnaire | ? | expression régulière(expression x (objet, classe, méthode)) | | type around | par reflexion (RTTI:run time type information) |
| JBossAOP | instanciation | {méthode, constructeur, greffon} x {appel, exécution} | via greffon (advice) | | signature, instanceof, joker, annotation | &&, !,|| | around | par accès reflective |
| SpringAOP | instanciation | exécution des méthodes | via greffon (advice) | cflow | expression régulière | && | before, after, returning, around, throws | par accès reflective |
Contrairement à AspectJ qui définit cinq types de greffon (before, after, after running, after throwing, around), il n'y a qu'un seul type de wrapper en JAC: around. En effet ce type est plus général et recouvre tous les autres

### Type de tissage et fonctionnalités

Comparaison des types de tissage et fonctionnalités :
| | Compilateur | Tissage | Déploiement | Exécution |
| AspectJ | compilateur aspectJ | compilation, chargement | statique | programme java |
| JAC | compilateur java | chargement, exécution | dynamique | invocation et gestion par le framework |
| JBossAOP | compilateur java, post traitement | compilation, exécution | dynamique | invocation et gestion par le framework |
| SpringAOP | compilateur java | chargement, exécution | dynamique | invocation et gestion par le framework |

## Conclusion

Les objets se sont avérés trop petits comme unités de réutilisation et insuffisants pour capturer des préoccupations transversales. De nouveaux paradigmes de programmation comme POA, sont apparus pour compléter la POO. Nous nous sommes donc attardés sur l'une des étapes clés de la POA : le tissage. Qu'il se fasse à la compilation ou au chargement, si un aspect ne peut pas être retiré une fois tissé alors on parle de tissage statique. Si par contre un aspect peut être retiré une fois tissé alors on a affaire au tissage dynamique.
À part les quatre frameworks que nous avons considérés, il y a de nouveaux frameworks qui font aussi de la transformation de code. Spoon permet de faire de l'analyse et la transformation de code source JAVA. Son extension Spoon-AOP a été prouvé capable de faire de la POA de façon flexible, efficace et intuitive, en pur JAVA grâce aux annotations.