AspectJ: differenze tra le versioni
Contenuto cancellato Contenuto aggiunto
m Bot: piccoli errori di battitura |
|||
Riga 6:
===Join point e pointcut===
Un concetto basilare di '''AspectJ''' è quello di join point. Un join point può essere intuitivamente definito come un certo istante nell' esecuzione del programma; ogni chiamata a un qualsiasi metodo di un oggetto qualunque potrebbe essere un join point, così come leggere il valore di una variabile
I pointcut invece descrivono le situazioni particolari che si vengono a creare durante l'
È possibile definire un pointcut in maniera estremamente dettagliata; si può ad esempio definire un pointcut che sia valido quando un qualsiasi metodo della [[Classe (informatica)|classe]] A viene chiamato, o ancora, definire un pointcut che è valido quando un metodo di un oggetto di classe A chiama il [[metodo]] xyz(int a
Un pointcut può contenere informazioni sui join point che lo compongono, quali ad esempio gli argomenti del metodo chiamato (se il pointcut contiene un join point definito dalla chiamata di un metodo) o lo specifico oggetto cui era diretta la chiamata (sempre che il pointcut contenga un join point consistente nella chiamata di un metodo di un oggetto). Facendo riferimento alla metafora precedente, i pointcut definiscono quando gli spettatori salgono sul palcoscenico
===Advice===
Riga 19:
quando un certo pointcut diventa valido . è importante notare che un advice può contenere esso stesso la definizione del pointcut che lo attiva. Un advice nella sua esecuzione può accedere ad eventuali
informazioni sui join point che lo compongono che il pointcut può
fornirgli
===Aspect===
Riga 31:
====Join points====
un join point può essere
call (void faiqualcosa(int))
Riga 39:
execution(void faiqualcosa(int))
La differenza tra un join point di tipo execution e uno di tipo call è molto semplice : un join point di tipo call corrisponde alla chiamata di un metodo da parte di un altro metodo
Esistono inoltre molti altri modi per individuare dei join point nel flusso del programma :
Riga 50:
set (byte B.valore )
sono dei join point che denotano, rispettivamente
initialization(B.new())
corrisponde alla creazione di un oggetto di classe B tramite un costruttore che non accetta parametri
initialization(C.new(String,int))
Riga 64:
adviceexecution()
Ci sono anche altri tipi di join point in aspectj
In aspectj esistono inoltre delle espressioni che permettono di definire degli insiemi di join point;
l' espressione
Riga 76:
definisce invece un insieme di join point corrispondenti alla chiamata dei metodi di nome
doSomething che siano stati dichiarati come pubblici
Un'
il seguente :
Riga 86:
====''Pointcut''====
Un pointcut è un join point
pointcut pc() : call(void doSomething(int))
Riga 95:
mette a disposizione dell'advice una variabile int i che sarà inizializzata al valore del parametro intero passato al metodo
void doSomething(int n)
i join point che accettano come input un unico parametro di tipo int . Facendo riferimento a pointcut che nelle loro definizioni hanno
pointcut wait(A1 ac, B2 bd) : call(void wait()) && this(ac) && target(bd)
esso corrisponde a un oggetto appartenente alla classe A1 che
è anche possibile definire un pointcut come un 'unione di due join point : tale poincut diventerà 'valido' quando l'esecuzione del programma raggiungera' uno qualsiasi (nella definizione si usa
l' OR logico) dei join point specificati . Ad esempio :
Riga 106:
poincut pt() : call(void calcola()) || execution(int moltiplica(int,int))
Tale pointcut coincide sia con la chiamata del metodo void calcola()
è anche possibile usare la negazione nella definizione di un pointcut :
Riga 112:
pointcut wait2(A1 ac, B2 bd) : call(void wait()) && !this(ac) && target(bd)
questo pointcut verrà attivato da una chiamata del metodo B2.wait()
In generale
esse sono : cflow e cflowbelow .
per mostrare la differenza tra i due
pointcut ct() : call(void sum()) ;
pointcut fl() : cflow(ct) ;
il pointucut fl individua l'insieme di join point generati nell'esecuzione del metodo void sum
pointcut fl2() : cflowbelow(ct) ;
questo pointcut fl2 corrispnderà all'insieme dei join point generati nell'esecuzione di void sum ,
ma non al join point generato dalla chiamata di void sum . il pointcut fl2 non contiene al suo interno il pointcut ct . cflow e cflowbelow sono due parole chiave usate frequentemente per definire pointcut che sono intersezioni di altri pointcut
ad esempio :
pointcut restart() : cflowbelow(execution(void wait()))) && call(void resume(int)) ;
In questo caso
Con within (nomeClasse) si indica l'insieme dei join point corrispondenti all' esecuzione di codice che sia , a livello di sorgenti
pointcut pi() : within(java.sql.*);
denota l'insime dei join point generati dal codice che è parte del package java.sql ; anologamente
pointcut pi2() : withincode(void insert(Object o));
Riga 143:
====Advice====
Gli advice sono degli insiemi di istruzioni che vengono eseguiti prima
Riga 161:
}
l' effetto di questo advice è di far stampare come messaggio a video
Un advice
after(): execution (void faQualcosa(..)) {tem.out.println(
}
Riga 172:
pointcut wait(A1 ac, B2 bd) : call(void wait()) && this(ac) && target(bd)
si
before (A1 ac , B2 bd ) : wait(ac,bd) {
Riga 179:
}
Bisogna ricordare che in java un metodo può terminare regolarmente oppure lanciando un'
Si veda il seguente codice :
Riga 190:
}
quest' altro verra' eseguito solo se il metodo faiQualcosa ha gettato un'
inoltre un advice del tipo after (..) returning
after (int a) returning : call(int moltiplica(int,int)) {
Riga 199:
}
analogamente
after (Exception e ) throwing : call(int moltiplica(int,int)) {
Riga 207:
====Aspetti====
Un aspetto modella una problematica trasversale dell' applicazione. Può contenere al suo interno definizioni di pointcut, advice, attributi e metodi, implementare un'interfaccia od estendere una classe; il viceversa ovviamente non vale.
Esistono aspetti astratti e aspetti concreti, esattamente così come esistono classi astratte e classi concrete; però, a differenza dell'OOP, nell'AOP un aspetto concreto non può estendere un altro aspetto concreto, ma solo un aspetto astratto.
Un esempio è il seguente :
Riga 277:
pointcut wait(A1 ac, B2 bd) : call(void wait()) && this(ac) && target(bd)
è possibile associare a ogni oggetto che genera un pointcut 'valido' un aspetto. Ossia, una istanza dell'aspetto viene creata ogni volta che il flusso del programma raggiunge il pointcut wait e all'oggetto in esecuzione (this, in Java) non è gia associata un'
aspect nomeaspetto perthis(wait(A1 ac, B2 bd)) { }
|