Top Banner
Architecture technique applicative Aspects Aspects Techniques Techniques Framework Java IBM « AspectJ 1.5 » Programmation Orientée Aspect (Aspect Oriented Programming) Ajout transparent de services techniques dans le code métier Outil de développement : Plug-in Elipse AJDT 1.2 / 1.3 « Découpler le code technique du code métier » Publication : juillet Catégorie : veille technolog Auteur : Jimmy Michel SI Version éditoriale : 2.0.0.0, le 14 mars avancé simple expert Niveau : Public : Architecte Dévelopeur Manager
56

Aspect avec AspectJ

Nov 01, 2014

Download

Technology

Architecture et développement d'Aspects avec le framework java AspectJ version 5.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Aspect avec AspectJ

Architecture technique applicative Aspects TechniquesAspects TechniquesFramework Java IBM « AspectJ 1.5 »

Programmation Orientée Aspect (Aspect Oriented Programming)

Ajout transparent de services techniques dans le code métierOutil de développement : Plug-in Elipse AJDT 1.2 / 1.3

« Découpler le code technique du code métier »

Programmation Orientée Aspect (Aspect Oriented Programming)

Ajout transparent de services techniques dans le code métierOutil de développement : Plug-in Elipse AJDT 1.2 / 1.3

« Découpler le code technique du code métier »

Publication : juillet 2005Catégorie : veille technologiqueAuteur : Jimmy Michel SIMEON

Version éditoriale : 2.0.0.0, le 14 mars 2006

avancésimple expertNiveau :

Public : ArchitecteDévelopeur Manager

Page 2: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Emergence de la programmation orientée Aspect

La programmation orientée aspect est l'une des 10 technologies clés, qui selon le MIT, "changeront le monde".« L’implémentation d’une préoccupation applicative est soit un composant soit un aspect »

Page 3: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Historique de la Programmation Orientée Aspect

1991, publication de Mr Gregor Kiczales coauteur « the Art of the Meta-Object protocol »

1996, Mr Gregor Kiczales responsable de l’équipe AOP chez XEROX PARC en Californie USA,

1997, présentation de l’AOP à l’ECOOP (European Conference on Object-Oriented Programming) langage D (JavaD) Christina Lopez, antérieur à Java AspectJ. Aspect-oriented software development (AOSD)

Aspect-Oriented Software Association http://aosd.net/ http://www.parc.xerox.com/research/csl/projects/aspectj/default.htmlRecherche supportée par PARC, NIST ATP and DARPA

Page 4: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Historique du Framework Java « AspectJ »

AspectJ 1997, AspectJ v0.1 créé par Chris Maeda et Gregor Kiczales, PARC Xerox.

Erik Hilsdale, Jim Hugunin, Wes Isberg, Mik Kersten and Gregor Kiczales 1998, première version utilisateur, la version 1.0 en nov. 2001. décembre 2002 livrée à la communauté Eclipse.ORG / IBM,

partiellement fondé par DARPA sous contrat F30602-97-C0246, AJDT : Adrian Colyer, Mik Kersten, Andy Clement, Julie Waterhouse Park

2005, AspectJ 5 (v1.5) intègre AspectWerkz Adrian Colyer AspectJ lead – IBM, Jonas Bonér AspectJ commiter – BEA AspectWerkz, créateur Jonas Bonér, sponsorisé par BEA, licence LGPL

Téléchargement des outils et de la documentation : http://aspectj.orghttp://www.eclipse.org/downloads/download.php?file=/technology/aspectj/dev/aspectj-1.5.0M2.jar récupérer le plug-in Eclipse : http://eclipse.org/ajdt email à l’équipe : [email protected] trouver plus d’information sur AOP: http://aosd.net

Page 5: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Acteurs du marché AOP(bonne pratique AOP des experts en développements)

Rod Johnson : Framework Spring AOP, AOP alliance auteur du livre «J2EE without EJB» Conteneurs léger (couplage lâche) vs conteneur lourd (couplage fort),

Bill Burke : Leader JBoss AOPAOP alliance

Jonas Bonér : framework AspectWerkz BEA SystemsAspectWerkz fusionne avec AspectJ !

Aspect Oriented Programming (Frameworks AOP), Separation Of Concerns (SoC).

Gregor Kiczales XEROX PARC : père de l’AOP et du framework AspectJAspecJ appartient à la communauté Eclipse / IBM

Page 6: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Objectifs de AOP (1) Améliorer la qualité du code

Éliminer toute duplication de code Centraliser les séquences d’instructions répétitives

Augmenter la productivité Limiter les redondances

Améliorer la cohérence globale de l’application Réduit la charge de développement Facilite la maintenance (et la lisibilité du code)

Réduire le besoin d’omniscience Re-centrer les connaissances sur l’activité principale éviterait :

La surcharge cognitive Les coûts de formations superflus Le temps perdu

Page 7: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Objectifs de AOP (2)

Découplage métier et technologique Limiter le couplage entre :

Objets (présentation, logique et domaine) Frameworks techniques

Mieux respecter les principes fondamentaux : L’inversion des dépendances (Le faible couplage)

Diminuer le coût de maintenance et augmenter la réutilisation

Découplage conceptuel et organisationnel Spécialistes métiers et techniques devraient pouvoir :

Travailler en parallèle Élaborer des modules complémentaires mais différents

Paralléliser le développement du code technique et du code métier,

Séparation des risques (expertises, formations, recettes) Amélioration de la productivité des équipes spécialisées

Page 8: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Découpler le code technique du code fonctionnel

Aspect techniques transverses : Journalisation logs applicative, persistance, transaction, sécurité, cache, chargement paresseux, etc.

Code métier : Logique : Lecture du solde, débit ou crédit, demande d’une

carte, etc Domaine : Compte bancaire, chéquier, cartes, etc.

Centraliser les traitements technique qui ne sont pas des comportements propres au métier

Page 9: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Visualisation des catégories d’aspects techniques dans un programme

Identification des Aspects techniques !

Page 10: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Modularité d’une préoccupation transverse

Aspect(s)

package org.apache.tomcat.session;

import java.io.IOException;import java.util.Enumeration;import java.util.Hashtable;import java.util.Vector;import org.apache.tomcat.catalina.*;import javax.servlet.http.Cookie;import javax.servlet.http.HttpSession;import org.apache.tomcat.util.StringManager;import org.w3c.dom.NamedNodeMap;import org.w3c.dom.Node;

/** * Standard implementation of the <b>Manager</b> interface that provides * no session persistence or distributable capabilities, but does support * an optional, configurable, maximum number of active sessions allowed. * <p> * Lifecycle configuration of this component assumes an XML node * in the following format: * <code> * &lt;Manager className="org.apache.tomcat.session.StandardManager" * checkInterval="60" maxActiveSessions="-1" * maxInactiveInterval="-1" /> * </code> * where you can adjust the following parameters, with default values * in square brackets: * <ul> * <li><b>checkInterval</b> - The interval (in seconds) between background * thread checks for expired sessions. [60] * <li><b>maxActiveSessions</b> - The maximum number of sessions allowed to * be active at once, or -1 for no limit. [-1] * <li><b>maxInactiveInterval</b> - The default maximum number of seconds of * inactivity before which the servlet container is allowed to time out * a session, or -1 for no limit. This value should be overridden from * the default session timeout specified in the web application deployment * descriptor, if any. [-1] * </ul> * * @author Craig R. McClanahan * @version $Revision: 1.1.1.1 $ $Date: 2000/05/02 21:28:30 $ */

public final class StandardManager extends ManagerBase implements Lifecycle, Runnable {

// ----------------------------------------------------- Instance Variables

/** * The interval (in seconds) between checks for expired sessions. */ private int checkInterval = 60;

/** * Has this component been configured yet? */ private boolean configured = false;

/** * The descriptive information about this implementation. */ private static final String info = "StandardManager/1.0";

/** * The maximum number of active Sessions allowed, or -1 for no limit. */ protected int maxActiveSessions = -1;

/** * The string manager for this package. */ private StringManager sm = StringManager.getManager("org.apache.tomcat.session");

/** * Has this component been started yet? */ private boolean started = false;

/** * The background thread. */ private Thread thread = null;

/** * The background thread completion semaphore. */ private boolean threadDone = false;

/** * Name to register for the background thread. */ private String threadName = "StandardManager";

// ------------------------------------------------------------- Properties

/** * Return the check interval (in seconds) for this Manager. */ public int getCheckInterval() {

return (this.checkInterval);

}

/** * Set the check interval (in seconds) for this Manager. * * @param checkInterval The new check interval */ public void setCheckInterval(int checkInterval) {

this.checkInterval = checkInterval;

}

/** * Return descriptive information about this Manager implementation and * the corresponding version number, in the format * <code>&lt;description&gt;/&lt;version&gt;</code>. */ public String getInfo() {

return (this.info);

}

/** * Return the maximum number of active Sessions allowed, or -1 for * no limit. */ public int getMaxActiveSessions() {

return (this.maxActiveSessions);

}

/** * Set the maximum number of actives Sessions allowed, or -1 for * no limit. * * @param max The new maximum number of sessions */ public void setMaxActiveSessions(int max) {

this.maxActiveSessions = max;

}

// --------------------------------------------------------- Public Methods

/** * Construct and return a new session object, based on the default * settings specified by this Manager's properties. The session * id will be assigned by this method, and available via the getId() * method of the returned session. If a new session cannot be created * for any reason, return <code>null</code>. * * @exception IllegalStateException if a new session cannot be * instantiated for any reason */ public Session createSession() {

if ((maxActiveSessions >= 0) && (sessions.size() >= maxActiveSessions)) throw new IllegalStateException (sm.getString("standardManager.createSession.ise"));

return (super.createSession());

}

// ------------------------------------------------------ Lifecycle Methods

/** * Configure this component, based on the specified configuration * parameters. This method should be called immediately after the * component instance is created, and before <code>start()</code> * is called. * * @param parameters Configuration parameters for this component * (<B>FIXME: What object type should this really be?) * * @exception IllegalStateException if this component has already been * configured and/or started * @exception LifecycleException if this component detects a fatal error * in the configuration parameters it was given */ public void configure(Node parameters) throws LifecycleException {

// Validate and update our current component state if (configured) throw new LifecycleException (sm.getString("standardManager.alreadyConfigured")); configured = true; if (parameters == null) return;

// Parse and process our configuration parameters if (!("Manager".equals(parameters.getNodeName()))) return; NamedNodeMap attributes = parameters.getAttributes(); Node node = null;

node = attributes.getNamedItem("checkInterval"); if (node != null) { try { setCheckInterval(Integer.parseInt(node.getNodeValue())); } catch (Throwable t) { ; // XXX - Throw exception? } }

node = attributes.getNamedItem("maxActiveSessions"); if (node != null) { try { setMaxActiveSessions(Integer.parseInt(node.getNodeValue())); } catch (Throwable t) { ; // XXX - Throw exception? } }

node = attributes.getNamedItem("maxInactiveInterval"); if (node != null) { try { setMaxInactiveInterval(Integer.parseInt(node.getNodeValue())); } catch (Throwable t) { ; // XXX - Throw exception? } }

}

/** * Prepare for the beginning of active use of the public methods of this * component. This method should be called after <code>configure()</code>, * and before any of the public methods of the component are utilized. * * @exception IllegalStateException if this component has not yet been * configured (if required for this component) * @exception IllegalStateException if this component has already been * started * @exception LifecycleException if this component detects a fatal error * that prevents this component from being used */ public void start() throws LifecycleException {

// Validate and update our current component state if (!configured) throw new LifecycleException (sm.getString("standardManager.notConfigured")); if (started) throw new LifecycleException (sm.getString("standardManager.alreadyStarted")); started = true;

// Start the background reaper thread threadStart();

}

/** * Gracefully terminate the active use of the public methods of this * component. This method should be the last one called on a given * instance of this component. * * @exception IllegalStateException if this component has not been started * @exception IllegalStateException if this component has already * been stopped * @exception LifecycleException if this component detects a fatal error * that needs to be reported */ public void stop() throws LifecycleException {

// Validate and update our current component state if (!started) throw new LifecycleException (sm.getString("standardManager.notStarted")); started = false;

// Stop the background reaper thread threadStop();

// Expire all active sessions Session sessions[] = findSessions(); for (int i = 0; i < sessions.length; i++) { StandardSession session = (StandardSession) sessions[i]; if (!session.isValid()) continue; session.expire(); }

}

// -------------------------------------------------------- Private Methods

/** * Invalidate all sessions that have expired. */ private void processExpires() {

long timeNow = System.currentTimeMillis(); Session sessions[] = findSessions();

for (int i = 0; i < sessions.length; i++) { StandardSession session = (StandardSession) sessions[i]; if (!session.isValid()) continue; int maxInactiveInterval = session.getMaxInactiveInterval(); if (maxInactiveInterval < 0) continue; int timeIdle = // Truncate, do not round up (int) ((timeNow - session.getLastAccessedTime()) / 1000L); if (timeIdle >= maxInactiveInterval) session.expire(); } }

/** * Sleep for the duration specified by the <code>checkInterval</code> * property. */ private void threadSleep() {

try { Thread.sleep(checkInterval * 1000L); } catch (InterruptedException e) { ; }

}

/** * Start the background thread that will periodically check for * session timeouts. */ private void threadStart() {

if (thread != null) return;

threadDone = false; thread = new Thread(this, threadName); thread.setDaemon(true); thread.start();

}

/** * Stop the background thread that is periodically checking for * session timeouts. */ private void threadStop() {

if (thread == null) return;

threadDone = true; thread.interrupt(); try { thread.join(); } catch (InterruptedException e) { ; }

thread = null;

}

// ------------------------------------------------------ Background Thread

/** * The background thread that checks for session timeouts and shutdown. */ public void run() {

// Loop until the termination semaphore is set while (!threadDone) { threadSleep(); processExpires(); }

}

}

StandardManager StandardSessionManagerpackage org.apache.tomcat.session;

import java.io.IOException;

import javax.servlet.http.Cookie;

import javax.servlet.http.HttpSession;

import org.apache.tomcat.catalina.*;

import org.apache.tomcat.core.Context;

import org.apache.tomcat.core.Request;

import org.apache.tomcat.core.Response;

import org.apache.tomcat.core.SessionManager;

import org.apache.tomcat.util.SessionUtil;

/**

* Specialized implementation of org.apache.tomcat.core.SessionManager

* that adapts to the new component-based Manager implementation.

* <p>

* XXX - At present, use of <code>StandardManager</code> is hard coded,

* and lifecycle configuration is not supported.

* <p>

* <b>IMPLEMENTATION NOTE</b>: Once we commit to the new Manager/Session

* paradigm, I would suggest moving the logic implemented here back into

* the core level. The Tomcat.Next "Manager" interface acts more like a

* collection class, and has minimal knowledge of the detailed request

* processing semantics of handling sessions.

* <p>

* XXX - At present, there is no way (via the SessionManager interface) for

* a Context to tell the Manager that we create what the default session

* timeout for this web application (specified in the deployment descriptor)

* should be.

*

* @author Craig R. McClanahan

*/

public final class StandardSessionManager

implements SessionManager {

// ----------------------------------------------------------- Constructors

/**

* Create a new SessionManager that adapts to the corresponding Manager

* implementation.

*/

public StandardSessionManager() {

manager = new StandardManager();

if (manager instanceof Lifecycle) {

try {

((Lifecycle) manager).configure(null);

((Lifecycle) manager).start();

} catch (LifecycleException e) {

throw new IllegalStateException("" + e);

}

}

}

// ----------------------------------------------------- Instance Variables

/**

* The Manager implementation we are actually using.

*/

private Manager manager = null;

// --------------------------------------------------------- Public Methods

/**

* Mark the specified session's last accessed time. This should be

* called for each request by a RequestInterceptor.

*

* @param session The session to be marked

*/

public void accessed(Context ctx, Request req, String id) {

HttpSession session=findSession(ctx, id);

if( session == null) return;

if (session instanceof Session)

((Session) session).access();

// cache the HttpSession - avoid another find

req.setSession( session );

}

// XXX should we throw exception or just return null ??

public HttpSession findSession( Context ctx, String id ) {

try {

Session session = manager.findSession(id);

if(session!=null)

return session.getSession();

} catch (IOException e) {

}

return (null);

}

public HttpSession createSession(Context ctx) {

return manager.createSession().getSession();

}

/**

* Remove all sessions because our associated Context is being shut down.

*

* @param ctx The context that is being shut down

*/

public void removeSessions(Context ctx) {

// XXX XXX a manager may be shared by multiple

// contexts, we just want to remove the sessions of ctx!

// The manager will still run after that ( i.e. keep database

// connection open

if (manager instanceof Lifecycle) {

try {

((Lifecycle) manager).stop();

} catch (LifecycleException e) {

throw new IllegalStateException("" + e);

}

}

}

/**

* Used by context to configure the session manager's inactivity timeout.

*

* The SessionManager may have some default session time out, the

* Context on the other hand has it's timeout set by the deployment

* descriptor (web.xml). This method lets the Context conforgure the

* session manager according to this value.

*

* @param minutes The session inactivity timeout in minutes.

*/

public void setSessionTimeOut(int minutes) {

if(-1 != minutes) {

// The manager works with seconds...

manager.setMaxInactiveInterval(minutes * 60);

}

}

}

ServerSessionManager

package org.apache.tomcat.session;

import org.apache.tomcat.util.*;import org.apache.tomcat.core.*;import java.io.*;import java.net.*;import java.util.*;import javax.servlet.http.*;

/** * * @author James Duncan Davidson [[email protected]] * @author Jason Hunter [[email protected]] * @author James Todd [[email protected]] */

public class ServerSessionManager implements SessionManager {

private StringManager sm = StringManager.getManager("org.apache.tomcat.session"); private static ServerSessionManager manager; // = new ServerSessionManager();

protected int inactiveInterval = -1;

static { manager = new ServerSessionManager(); }

public static ServerSessionManager getManager() { return manager; }

private Hashtable sessions = new Hashtable(); private Reaper reaper;

private ServerSessionManager() { reaper = Reaper.getReaper(); reaper.setServerSessionManager(this); reaper.start(); }

public void accessed( Context ctx, Request req, String id ) { ApplicationSession apS=(ApplicationSession)findSession( ctx, id); if( apS==null) return;

ServerSession servS=apS.getServerSession(); servS.accessed(); apS.accessed();

// cache it - no need to compute it again req.setSession( apS ); }

public HttpSession createSession(Context ctx) { String sessionId = SessionIdGenerator.generateId(); ServerSession session = new ServerSession(sessionId); sessions.put(sessionId, session);

if(-1 != inactiveInterval) { session.setMaxInactiveInterval(inactiveInterval); } return session.getApplicationSession( ctx, true ); }

public HttpSession findSession(Context ctx, String id) { ServerSession sSession=(ServerSession)sessions.get(id); if(sSession==null) return null;

return sSession.getApplicationSession(ctx, false); }

// XXX // sync'd for safty -- no other thread should be getting something // from this while we are reaping. This isn't the most optimal // solution for this, but we'll determine something else later.

synchronized void reap() { Enumeration enum = sessions.keys();

while (enum.hasMoreElements()) { Object key = enum.nextElement(); ServerSession session = (ServerSession)sessions.get(key);

session.reap(); session.validate(); } }

synchronized void removeSession(ServerSession session) { String id = session.getId();

session.invalidate(); sessions.remove(id); }

public void removeSessions(Context context) { Enumeration enum = sessions.keys();

while (enum.hasMoreElements()) { Object key = enum.nextElement(); ServerSession session = (ServerSession)sessions.get(key); ApplicationSession appSession = session.getApplicationSession(context, false);

if (appSession != null) { appSession.invalidate(); } } }

/** * Used by context to configure the session manager's inactivity timeout. * * The SessionManager may have some default session time out, the * Context on the other hand has it's timeout set by the deployment * descriptor (web.xml). This method lets the Context conforgure the * session manager according to this value. * * @param minutes The session inactivity timeout in minutes. */ public void setSessionTimeOut(int minutes) { if(-1 != minutes) { // The manager works with seconds... inactiveInterval = (minutes * 60); } }}

SessionInterceptorpackage org.apache.tomcat.request;

import org.apache.tomcat.core.*;import org.apache.tomcat.util.*;import java.io.*;import java.net.*;import java.util.*;import javax.servlet.http.*;

/** * Will process the request and determine the session Id, and set it * in the Request. * It also marks the session as accessed. * * This implementation only handles Cookies sessions, please extend or * add new interceptors for other methods. * */public class SessionInterceptor extends BaseInterceptor implements RequestInterceptor {

// GS, separates the session id from the jvm route static final char SESSIONID_ROUTE_SEP = '.'; int debug=0; ContextManager cm; public SessionInterceptor() { }

public void setDebug( int i ) { System.out.println("Set debug to " + i); debug=i; } public void setContextManager( ContextManager cm ) { this.cm=cm; }

public int requestMap(Request request ) { String sessionId = null;

Cookie cookies[]=request.getCookies(); // assert !=null for( int i=0; i<cookies.length; i++ ) { Cookie cookie = cookies[i]; if (cookie.getName().equals("JSESSIONID")) { sessionId = cookie.getValue(); sessionId=validateSessionId(request, sessionId); if (sessionId!=null){ request.setRequestedSessionIdFromCookie(true); } } } String sig=";jsessionid="; int foundAt=-1; if( debug>0 ) cm.log(" XXX RURI=" + request.getRequestURI()); if ((foundAt=request.getRequestURI().indexOf(sig))!=-1){ sessionId=request.getRequestURI().substring(foundAt+sig.length()); // rewrite URL, do I need to do anything more? request.setRequestURI(request.getRequestURI().substring(0, foundAt)); sessionId=validateSessionId(request, sessionId); if (sessionId!=null){ request.setRequestedSessionIdFromURL(true); } } return 0; }

// XXX what is the correct behavior if the session is invalid ? // We may still set it and just return session invalid. /** Validate and fix the session id. If the session is not valid return null. * It will also clean up the session from load-balancing strings. * @return sessionId, or null if not valid */ private String validateSessionId(Request request, String sessionId){ // GS, We piggyback the JVM id on top of the session cookie // Separate them ...

if( debug>0 ) cm.log(" Orig sessionId " + sessionId ); if (null != sessionId) { int idex = sessionId.lastIndexOf(SESSIONID_ROUTE_SEP); if(idex > 0) { sessionId = sessionId.substring(0, idex); } } if (sessionId != null && sessionId.length()!=0) { // GS, We are in a problem here, we may actually get // multiple Session cookies (one for the root // context and one for the real context... or old session // cookie. We must check for validity in the current context. Context ctx=request.getContext(); SessionManager sM = ctx.getSessionManager(); if(null != sM.findSession(ctx, sessionId)) { sM.accessed(ctx, request, sessionId ); request.setRequestedSessionId(sessionId); if( debug>0 ) cm.log(" Final session id " + sessionId ); return sessionId; } } return null; }

public int beforeBody( Request rrequest, Response response ) { String reqSessionId = response.getSessionId(); if( debug>0 ) cm.log("Before Body " + reqSessionId ); if( reqSessionId==null) return 0;

// GS, set the path attribute to the cookie. This way // multiple session cookies can be used, one for each // context. String sessionPath = rrequest.getContext().getPath(); if(sessionPath.length() == 0) { sessionPath = "/"; }

// GS, piggyback the jvm route on the session id. if(!sessionPath.equals("/")) { String jvmRoute = rrequest.getJvmRoute(); if(null != jvmRoute) { reqSessionId = reqSessionId + SESSIONID_ROUTE_SEP + jvmRoute; } }

Cookie cookie = new Cookie("JSESSIONID", reqSessionId); cookie.setMaxAge(-1); cookie.setPath(sessionPath); cookie.setVersion(1); response.addHeader( CookieTools.getCookieHeaderName(cookie), CookieTools.getCookieHeaderValue(cookie)); cookie.setVersion(0); response.addHeader( CookieTools.getCookieHeaderName(cookie), CookieTools.getCookieHeaderValue(cookie)); return 0; }

/** Notification of context shutdown */ public void contextShutdown( Context ctx ) throws TomcatException { if( ctx.getDebug() > 0 ) ctx.log("Removing sessions from " + ctx ); ctx.getSessionManager().removeSessions(ctx); }

}

Comment extraire le code technique du code métier

Code technique

Code métier

AOP

Page 11: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Vocabulaire technique de l’AOP (1)

Aspect : un module unitaire (Aspect) définissant du code à injecter (Advice), leurs

points d'activation (PointCut / joint point Model) pour satisfaire à des préoccupations transverses (crosscutting conserns),

Cross-cutting concerns (préoccupations transverses ) : préoccupations technique représenté par la répartition du code technique

dans le code métier pour satisfaire des contraintes techniques (non lié à l’algorithme métier)

Joint Point (point de jonction) : décri un point évènementiel précis (discret) dans le flot d’exécution

programme où il est valide d'insérer un greffon (advice).

Joint Point Model (modèle de point de jonction) : ensemble des points d’emplacements discrets accessibles par l’Aspect et

exposés par le langage de programmation de l’application.

Page 12: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Vocabulaire technique de l’AOP (2)

Advise (greffon) un programme qui sera activé à un certain point d'exécution de l’application,

précisé par un point de jonction,

Weaving (tissage ou tramage) : insertion statique (compilation) ou dynamique (au runtime ou au chargement) de

greffons aux points de jonctions.

Pointcut (point de coupe ou de coupure) : ligne imaginaire reliant les points de jonctions ou seront insérés un greffon par

le tisseur d'aspect (aspect weaver).

Page 13: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Principes de l’AOP

1. Identifier les préoccupations techniques2. Implémenter chaque aspect technique dans une unité appelé un “Aspect”3. Tisser les préoccupation avec un tisseur (Weave the concerns with a weaver)

modules

Business logic

Tissage à l’exécution (dynamique) ou à la compilation (tissage statique)

Besoins TissageSpe

ctre

des

préo

ccup

ation

s

Page 14: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Couplage fort du code technique et métier (l’évolution du code technique impacte le code métier)

Design Pattern,Conteneur J2EE

(Tx, sécurité, etc.)Etc.

Besoins techniques

Logique DomaineDonnéesutilisateurs

Co u

p la g

e

Co u

p la g

e

couplage couplage couplage

Application Métier Processus et domaine métier

Données MétierAccès aux données métier

Interface Utilisateur

Présentation (projet)Multi-médias

Navigation

Intégratio

n

ress

ources

Page 15: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Couplage fort du code technique et métier (l’évolution du code technique impacte le code métier)

Présentations Logiques DomainesCode métier

ressources

© Auteur : jimmy Siméon

Framework, Design Pattern, Composant

(utilise)

Sécurité TransactionACID

CommunicationDistante (RMI, etc.)

Persistance

Cache, pool, log, etc.

Conteneur logiciel

APItechnique

utilisateurs

Code technique Le code technique utilise les API techniques via un couplage par implémentation

(utilise)

Conception technique

Co u

p la g

efo

rt

Co u

p la g

efo

rt

Sans AOPCode technique

Aspects

Page 16: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Découpler les couches techniques et métiers(Programmation Orientée Aspects et Architecture Orientée Service)

utilisateurs Présentations Logiques Domaines

ressources

Code des Aspects techniques (Préoccupations transverses) (Appels aux APIs Techniques, utilisation de Design Pattern)

Code métier (instances de classes simples),

(tissage)

Conteneur logiciel(utilise)

API techniques

Co u

p la g

efa

ible

Co u

p la g

efa

ible

Avec AOP

Aspects

Page 17: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Aspect dans un page JSP (Java Server Pages)

%RACINE_PROJET%

MyWebApp

source

jsp

classes

lib

Aspectjrt.jar

Page.jsp

Page_jsp.javaMyAspect.java

Page_jsp.classMyAspect.class

Code JSPJava Server Pages

Page.jsp

CompilateurJSPjspc

ServletPage_jsp.java

CompilateurAspectJ

ajc

p-codetissé

Page_jsp.classMyAspect.class

AspectMyAspect.aj(ou MyAspcet.java)

Aspectjrt.jar

Public pointcut pcd(HttpServvletRequest rq, HttpServletResponse rs): execution(* * MyServlet.doGet(HttpSerletRequest, HttpServletResponse))&& args(rq, rs);

before(HttpServletRequest rq, HttpServletResponsse rs) throws IOException : pcd(rq, rs){//Code de l’advice}

Page 18: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

« Design Patterns » transparent (orienté Aspect)

Pourquoi concevoir des Design Patterns AOP De nombreux Design Patterns sont transversaux et donc

difficilement modularisable à l’aide de la POO Permettre à un objet de participer à plusieurs DP différents de

façons transparente

Popularisation des Design Patterns AOP Jan Hannemann et de Gregor Kiczales, article « Design

Pattern Implementation in Java and AspectJ », en 2002 à la conférence OOPSLA.

Page 19: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Extraire le code technique puis le propager dans le code métier au dernier moment !

Phase de développement : Identifier les préoccupations transverse et les factoriser (sous forme d’Aspects) Modularisation du code

Phase d’utilisation : Propager les « Aspects » dans l’application métier : à la compilation (tissage statique), au chargement des classes dans la JVM, à l’exécution (tissage chaud).

AOP myths and realities, http://www-128.ibm.com/developerworks/java/library/j-aopwork15/

14 Feb 2006, Ramnivas Laddad ([email protected]), AOP@Work

Page 20: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Trois type de Tissages du code métier

Tissage à la compilation Tissage statique Aspect J < version 1.5

Tissage au chargement de la classe dans la JVM LTW : Load–Time Weaving AspectJ 5

Tissage à l’exécution Tissage à l’aide d’objet Proxy de l’API J2SE ou via la manipulation

du byte-code avec GCLIB JAC, Spring AOP, JBoos AOP

Page 21: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Syntaxe du descripteur de point de coupe AspectJ(PCD : PointCut Descriptor)

PointCut Descriptor

visibility-modifier publiic, private,Protected, package ParameterList

Page 22: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Descripteur de déploiement AspectJ(Schéma identique à AspectWerkz)

Annotations dans AspectJ 5 (version 1.5)

Contexte exposé par les annotations

Page 23: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Code d’une application de e-Banking

public class ATMBean implements SessionBean { javax.ejb.SessionContext ejbContext; javax.transaction.UserTransaction ut; public void transfer(int fromAcctID,int toAcctId,double amount) throws InsufficientFundsException, FinderException { // find accounts ... ut=ejbContext.getUserTransaction(); ut.begin(); try { fromAccount.withdraw(amount); toAccount.deposit(amount); ut.commit(); } catch(Exception ex) { ut.rollback(); throw new EJBException("transaction rollbacked"); } } public void ejbCreate() {...} public void ejbRemove() {...} public void ejbActivate() {...} public void ejbPassivate() {...} public void setSessionContext(javax.ejb.SessionContext sc) { ejbContext=sc; }}

Aspects EJB et Transactionnel dans le code métier !

Exemple d’utilisation

des aspects

métier

technique

métier

technique

technique

Page 24: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Modularisation des Aspects techniques

public aspect SessionBeanAspect { declare parents: ATM implements SessionBean; javax.ejb.SessionContext ATM.ejbContext;. public void ATM.ejbCreate() throws CreateException {...} public void ATM.ejbRemove() {...} public void ATM.ejbActivate() {...} public void ATM.ejbPassivate() {...} public void ATM.setSessionContext(SessionContext sc) {...}}

public aspect TransactionAspect { javax.transaction.UserTransaction ATM.ut; before(): call(* Account.withdraw(..)) && withincode(* ATM.transfer(..)) { ut=ejbContext.getUserTransaction(); ut.begin(); } after(): call(* Account.deposit(..)) && withincode(* ATM.transfer(..)) { ut.commit(); } after() throwing(Exception ex) throws EJBException: call(* Account.withdraw(..)) || call(* Account.deposit(..)) { ut.rollback(); throw new EJBException("transaction rollbacked");} }

Extraction du code technique dans deux préoccupations

Exemple d’utilisation

des aspects

Inter-typedefinition

Ce qui fait qu’une classe soit un EJB

Ce qui fait qu’une classe soit transactionnelle

Technique« Aspect

Transaction »

Technique« Aspect

EJB »

Page 25: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Code métier épuré des aspects du code technique

public class ATM { public void transfer(int fromAcctID,int toAcctId,double amount) throws InsufficientFundsException, FinderException { // find accounts ... fromAccount.withdraw(amount); toAccount.deposit(amount); }}

Exemple d’utilisation

des aspects

Page 26: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Code AOP « AspectJ » dans Eclipse plug-in AJDTclasse d’aspect, pointcut, types before() after() et around()

Plusieurs PCD et Advice par A

spect

Chaque Advise est associé à un PCD

marqueur

PCD : Descripteur de Point de Coupe

Page 27: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Perspective du Plug-in AJDT dans Eclipse (Cross Reference et Outline)

Page 28: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Visualiseur d’aspects (Pointcut « execution » et advise « before et after »)

Page 29: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Annotations AspectJ 1.5 décrivant un aspect @Aspect, @Pointcut, @Before et introspection de type JoinPoint

Annotations = Jdk 1.5 et AspectJ 1.5

(la classe métier)

Page 30: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Configuration XML « META-INF/aop.xml » tissage LTW (Load-Time Weaving)

Page 31: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Composition d’Aspects

Quand ? Intervient en phase de conception et implémentation d’un projet

applicatif

Comment ? Héritage et abstraction d’Aspects

Points de vigilances ? Incompatibilité (ou collision d’intérêts) Redondances Dépendances

Aspect privilégié Possibilité d’accéder à tous les attributs et à toutes les méthodes

d’une application et ce quelle que soit leur visibilité. Syntaxe du code : privilegied aspect MyAspect {…}

Page 32: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

AOP approche orthogonale à la POO

Approche orthogonale

Classe Aspect1 Classe Aspect2

Tissage du code

Greffon (Advise)Méthode d’aspect(code à injecter)

Point de jonction

Point de coupe

Descripteur de point de coupe(points de jonctions à atteindre)

Ordonnancement de la projection des aspects

Aspect abstrait

© Auteur : jimmy Siméon

Page 33: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Décompilation d’une classe tissée par un Aspect

Après le Tissage d’un Aspect

Classe métier décompilée

Page 34: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Décompilation de la classe Java d’Aspect

Classe d’Aspect décompilée

Page 35: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Développement d’aspects en équipe

Développeurs d’Aspects techniques

Modules d’aspects

Développeurs du code Métier

Code métierConteneur technique

Tissage et déploiementArchitecte d’AspectIntégrateur

Frameworks,

design patterns,…Aspects techniques transverses,…

Framework AOP, design Pattern AOP

© Auteur : jimmy Siméon

Extraction des aspects

Page 36: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Benchmark AOP réalisé par Alexandre VASSEUR http://docs.codehaus.org/display/AW/AOP+Benchmark

Valeurs des données en nano seconde

Page 37: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Tisseurs d'aspects pour différents langages En Java :

AspectJ (http://eclipse.org/aspectj/) JAC (http://www.aopsys.com/jac.html) (Java Aspect Components) AspectWerkz, JBoos AOP, Spring AOP, Hyper/J

En C++ : AspectC++ (http://www.aspectc.org/)

En C#, VB.NET : AspectDNG (http://sourceforge.net/projects/aspectdng/) Aspect#, LOOM.NET

En PHP : PHPaspect (http://phpaspect.org)

En C : Aspect-C (http://www.cs.ubc.ca/labs/spl/projects/aspectc.html)

Page 38: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Avantages

Maintenabilité accrue : chaque module d’aspect peut être maintenu indépendamment des autres,

Meilleure réutilisabilité : on n'a pas besoin de se préoccuper des évolutions futures : des nouvelles

fonctionnalités pourront être implémentées dans de nouveaux modules qui intéragiront avec le système du travers des aspects.

Gain de productivité : le programmeur ne se préoccupe que de l’aspect de l'application qui le concerne, ce

qui simplifie son travail, et permet d'augmenter la parallélisation du développement.

Amélioration de la qualité du code : La simplification du code qu'entraîne la programmation par aspect permet de le

rendre plus lisible et donc de meilleure qualité.

Rodin : Le penseur

Page 39: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Désavantages

Maîtrise de la génération automatique de code la production automatique de code non maîtrisée par le développeur déboguage plus difficile à analyser lors des phases de mise au point

des logiciels. Le plug-in Eclipse AJDT est indispensable pour passer de façon transparente, en mode déboguage, du code d'une classe métier à celui d'une classe aspect (technique).

Nouvelle façon de penser la conception d’application : Approche AOP transverse (orthogonale) à la POO (hiérarchie verticale) Plusieurs aspect sur un même point de jonction (complexe), pauvreté de

la composition d’aspects (permet de rester simple).

Rodin : Le penseur

Page 40: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Qu’est-ce que nous réserve l’avenir ?

Richesse (complexité) ou simplicité (pauvreté) d’un langage ? Quand privilégier la réutilisation et l’abstraction ? Jusqu’à quel niveau de réutilisation et d’abstraction faut t’il aller ?

Quel est la bonne profondeur d’isolement des couches à appliquer ? Réutilisation des couches présentations, applications et données ? Préconiser l’isolation du code métier des services techniques (conteneurs

légers vs lourds, aspects) ? Préconisation de conteurs techniques (Frameworks, Design Patterns,

composants d’infrastructure) ? Utilisation de progiciels métiers (frameworks métier 80%-20%) ou développer

une application métier spécifique ?

Pérennité, transitions et changements à accompagner ? Programmation orienté objet, méta-programmation et orientée aspect, Model Driven Architecture.

Rodin : Le penseur

Page 41: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Bibliographie utilisée pour cette présentation et e-Bibliographie

Palo Alto Research Center : http://www.parc.com/

Communauté de promotion de la programmation orientée aspect http://aosd.net/

The Server side, articles, discussion sur les tisseurs d’aspects http://www.theserverside.com

/news/thread.tss?thread_id=18502

Martin Fowler : Design Pattern IoC / DI (Inversion of Control / Dependancy Injection)« The Hollywood principle : Don’t call us, we’ll call you »

(DIP : Dependency Injection Principle)

Page 42: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Bibliographie

D’autres livres disponibles en librairies (hors bibliographie) :

Professional programming Software 2.0« Introducing AspectJ », page 32Russ Miles, author of the AspectJ Cookbook (O’Reilly) and Senior Technologist for General Dynamics United Kingdom Limited ([email protected])

Page 43: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

e-Bibliographie

Palo Alto Research Center : http://www.parc.com/

Communauté de promotion de la programmation orientée aspect http://aosd.net/, http://aosd.net/2005/archive/AspectJ5.pdf

AspectJ Project che Eclipse.ORG http://dev.eclipse.org/viewcvs/indextech.cgi/~checkout~/aspectj-home/index.html

Communauté et tutoriaux AspectJ, articles, AJDT http://www.aspectprogrammer.org/

OnJava.COM, article sur le chargement paresseux d’objets (lazy loading) avec AspectJ : http://www.onjava.com/pub/a/onjava/2004/03/17/lazyAspects.html (Russell Miles 03/17/2004 )

The Server side, articles, discussion sur les tisseurs d’aspects http://www.theserverside.com/news/thread.tss?thread_id=18502

IBM developerworks http://www-106.ibm.com/developerworks/java/library/j-aspectj/index.html

Application-servers.COM http://www.application-servers.com/stories.do?reqCode=wholeStory&sid=2005-01-20-21:24:10

Javaworld.COM http://www.javaworld.com/javaworld/jw-01-2002/jw-0118-aspect_p.html

Page 44: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

ANNEXE

Page 45: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Le créateur du Framework AspectJ

Undergraduate Study M.I.T. (1978-1983); Research Staff, MIT Lab for Computer Science (1980-1983); Member of Technical Staff, Symbolics Inc. (1983-1984);

Member of Research Staff, Xerox PARC (1984-1999); Manager, Software Design Area, Xerox PARC (1992-1999); Principal Scientist, Xerox PARC (1996-1999);

Professor, University of British Columbia (1999-); Xerox/Sierra Systems/NSERC Software Design Chair, UBC (1999-).The University of British Columbia2329 West Mall Vancouver, BC Canada V6T 1Z4

Mr Grégor KICZALESMIT

Page 46: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Outils AJDT « AspectJ Development Tools »plug-in Eclipse

Page 47: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Installation de AJDT 1.2 (1)

Page 48: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Installation de AJDT 1.2 (2)

Page 49: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Plug-in Eclipse « AJDT 1.2 »

Page 50: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Framework AspectJ 1.5 dans AJDT 1.2

Page 51: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Run-Time « aspectrt.jar »

Page 52: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Plug-in AJDT 1.3.0 et 1.2.1

Load-time Weaving (AJDT 1.2.1 and 1.3.0).

Qu’est-ce qui a changé (refactoring)Crosscutting Comparison view

Page 53: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

« Design Patterns » applicables à l’AOP

Page 54: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Outil AspectBrowser plug-in Eclipse(University of California, San Diego)

Department of Computer Science and EngineeringUniversity of California, San Diego

Plug-in Eclipse Open Source

Fonctions pour les Aspects : Création, Visualisation Graphique, Colorisation du code, Recherche

Outils sous licence :« Common Public License »

Page 55: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Outil ActiveAspect plug-in Eclipse(University of British Columbia)

This project is part of the M.Sc. research of Wesley Coelho

under the supervision of Gail Murphy

at the Software Practices Lab, Department of Computer

Science, University of British Columbia,

Canada.

http://www.cs.ubc.ca/labs/spl/projects/activeaspect/

Page 56: Aspect avec AspectJ

Aspect-Oriented Software Development Jimmy SIMEON, mai - juillet 2005

Analyse du modèle existant