Université Claude Bernard Lyon 1 - Master informatique

TP - Programmation Orientée Aspects (POA)

Objectifs pédagogiques

Comprendre et mettre en œuvre les grands principes de la POA ; utiliser l’outil AspectJ en Java.

Références :

Introduction

Durant ce TP, vous utiliserez un IDE (Eclipse ou IntelliJ) pour la programmation Java et son plugin AspectJ Development Tools (AJDT) pour la programmation des aspects. Vous trouverez la dernière version d'Eclipse (pour Windows, Linux et Mac OS), ainsi que le zip du plugin AJDT dans le répertoire "enseignement/Installs" de ma page.

Installation d'AspectJ :

Avant de démarrer, vous allez installer le plugin AJDT dans votre IDE (sur les machines des salles de TP ou sur votre propre machine). Selon votre IDE :

Eclipse
menu : Help -> Install New Software -> Add -> Archive.
IntelliJ
suivez la procédure indiquée ici.

Application source

Vous allez travailler sur une application de gestion de bookmarks de sites web dont une implémentation basique est accessible sur la forge, dans le projet nommé tp-m1-aspects-base. Le diagramme de classes UML de cette application est disponible . La fonction main de l'application est située dans le dossier "src". Elle instancie un Annuaire (chargé de réaliser le métier en répondant aux requêtes d'un client) et d'une interface utilisateur (AnnuaireUI), qui interroge l'annuaire. La classe Annuaire instancie à son tour les autres classes de l'application, et notamment un objet d'accès aux données (SiteXMLDAO).

Prise en main d’AspectJ

  1. Créez un projet AspectJ vide, importez-y l'application d'annuaire et exécutez-la.
    N'oubliez pas le fichier XML qui contient les données.
  2. Créez un nouvel aspect dans le projet, tant qu’à faire dans un package nommé « logging », avec le code en annexe.
  3. Faites tourner ce programme et vérifiez la création et le remplissage du fichier log.txt dans le répertoire racine du projet.

Modification d’un aspect existant

Reprenez le code de l’aspect ALog en suivant les étapes ci-dessous :

Conception d’un aspect

Dans cette partie, vous allez concevoir un nouvel aspect (que vous appellerez « APersist »), qui sera utilisé pour dissocier la gestion de la persistance du code métier de l’application. Plus précisément, il s’agit de modifier les classes de l'annuaire de façon à ce que la sauvegarde et le chargement de ce dernier se fasse via un aspect. Autrement dit toute référence à la sauvegarde et au chargement de l'annuaire doit disparaître du code source de ces classes.

Pour cela, vous suivrez la méthode suivante :

  1. Passer en revue les éléments de votre application, et déterminer les classes métier et celles qui relèvent du traitement de la persistance. Séparer ces deux préoccupations dans des packages différents.
  2. Repérer ensuite les crosscutting concerns correspondant aux échanges de messages entre objets matérialisant le passage de l’une à l’autre des préoccupations (métier à persistance).
  3. Formaliser les points de coupe permettant de les intercepter et supprimer les instructions correspondantes du code métier.
  4. Mettre en place des code advices qui appellent les fonctionnalités de persistance désirées.
  5. Repérer les éventuelles responsabilités « mixtes » entre des classes. Déplacer ce qui relève de la persistance dans l’aspect en utilisant des déclarations inter-types.

Annexe : code de l’aspect ALog

package logging;

import java.io.FileWriter;

public aspect ALog {
	FileWriter logFile = null;

	/**
	 * Constructeur de l'aspect : initialise le fichier de log
	 */
	public ALog() {
		try {
			logFile = new FileWriter("log.txt", true);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Point de coupe qui intercepte les appels à la méthode println
	 * @param message le texte en paramètre de la méthode println
	 */
	pointcut affichage(Object message) : args(message) && call(void java.io.PrintStream.println(*));

	/**
	 * Code advice contenant le code à exécuter lorsque l'aspect est déclenché
	 * @param message le message à afficher
	 */
	after(Object message) : affichage(message) {
		try {
			logFile.write(new java.util.Date().toString() + " : " + message.toString());
			logFile.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
Licence Creative Commons
Valid XHTML 1.0 Strict