lang:java:aspectj
Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
| lang:java:aspectj [2016/12/15 00:05] – [Déclaration d'un aspect] : ajout des annotations root | lang:java:aspectj [2020/04/26 22:39] (Version actuelle) – Conversion de <note> vers <WRAP> root | ||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| - | [[http:// | + | [[http:// |
| - | [[https:// | + | [[https:// |
| =====Déclaration d'un aspect===== | =====Déclaration d'un aspect===== | ||
| Ligne 20: | Ligne 20: | ||
| =====Déclaration d'un point de coupe===== | =====Déclaration d'un point de coupe===== | ||
| + | Sans annotation | ||
| <code java> | <code java> | ||
| pointcut evaluation(EventHandler h): target(h) && | pointcut evaluation(EventHandler h): target(h) && | ||
| call(public void *.handleEvent()); | call(public void *.handleEvent()); | ||
| + | </ | ||
| + | |||
| + | La dénomination exacte pour trouver le nom d'un méthode est : '' | ||
| + | |||
| + | |||
| + | Avec annotation | ||
| + | <code java> | ||
| + | @Pointcut(" | ||
| + | private void CoupureIncI(int x, C c) { | ||
| + | } | ||
| </ | </ | ||
| Ligne 49: | Ligne 60: | ||
| La méthode '' | La méthode '' | ||
| - | [[http:// | + | [[http:// |
| * '' | * '' | ||
| Pour le constructeur, | Pour le constructeur, | ||
| + | |||
| =====Déclaration d'un advice===== | =====Déclaration d'un advice===== | ||
| Utilisation d'un point de coupe (advice) : | Utilisation d'un point de coupe (advice) : | ||
| Ligne 64: | Ligne 76: | ||
| <code java> | <code java> | ||
| - | around() : call(Display.update()) { if (! Display.disabled()) proceed();} | + | // Si la fonction update ne renvoie rien. |
| + | around() : call(Display.update()) { | ||
| + | | ||
| + | | ||
| + | } | ||
| + | |||
| + | // Si la fonction update renvoie quelque chose. | ||
| + | Object around() : call(Display.update()) { | ||
| + | if (! Display.disabled()) | ||
| + | return proceed(); | ||
| + | return null; | ||
| + | } | ||
| </ | </ | ||
| Ici, le point de coupe est directement directement défini dans l' | Ici, le point de coupe est directement directement défini dans l' | ||
| - | Exemple sans annotation : | ||
| <code java> | <code java> | ||
| + | @Around(" | ||
| + | // Mettre void à la place de Object si la méthode setAge ne renvoie rien | ||
| + | public Object twiceAsOld(ProceedingJoinPoint thisJoinPoint, | ||
| + | // En cas de méthode static, pas besoin de joinPoint.getTarget(). | ||
| + | return thisJoinPoint.proceed(new Object[]{i*2, | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Exemple sans annotation : | ||
| + | <file java Log.aj> | ||
| public aspect Log { | public aspect Log { | ||
| pointcut evaluation(EventHandler h): target(h) && | pointcut evaluation(EventHandler h): target(h) && | ||
| call(public void *.handleEvent()); | call(public void *.handleEvent()); | ||
| - | // Le pointcut et after ont la même signature. Je ne sais pas si c' | + | // Le pointcut et after ont la même signature, sinon, ce n' |
| - | // indispensable mais ça a toujours été le cas dans les exemples que j'ai trouvé. | + | // de capturer des éléments |
| after(EventHandler h): | after(EventHandler h): | ||
| System.out.println(" | System.out.println(" | ||
| } | } | ||
| } | } | ||
| - | </code> | + | </file> |
| - | <code java> | + | <file java ProceedAspect.aj> |
| public aspect ProceedAspect { | public aspect ProceedAspect { | ||
| pointcut setAge(int i): call(* setAge(..)) && args(i); | pointcut setAge(int i): call(* setAge(..)) && args(i); | ||
| Object around(int i): setAge(i) { | Object around(int i): setAge(i) { | ||
| + | // Les trois variables thisJoinPoint, | ||
| + | // s' | ||
| return proceed(i*2); | return proceed(i*2); | ||
| } | } | ||
| } | } | ||
| - | </code> | + | </file> |
| Et en version annotation Java 5 : | Et en version annotation Java 5 : | ||
| - | <code java> | + | <file java Log.java> |
| import org.aspectj.lang.annotation.After; | import org.aspectj.lang.annotation.After; | ||
| import org.aspectj.lang.annotation.Aspect; | import org.aspectj.lang.annotation.Aspect; | ||
| Ligne 99: | Ligne 133: | ||
| @Aspect | @Aspect | ||
| public class Log { | public class Log { | ||
| - | @After(" | + | @After(" |
| - | public void LogHandleEvent(EventHandler h) | + | // Chacun des champs est facultatif. |
| + | public void LogHandleEvent(JoinPoint thisJoinPoint, | ||
| + | JoinPoint.StaticPart thisJoinPointStaticPart, | ||
| + | JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart) | ||
| { | { | ||
| System.out.println(" | System.out.println(" | ||
| } | } | ||
| } | } | ||
| - | </code> | + | </file> |
| - | <code java> | + | <file java ProceedAspect.aj> |
| @Aspect | @Aspect | ||
| public class ProceedAspect { | public class ProceedAspect { | ||
| Ligne 115: | Ligne 152: | ||
| @Around(" | @Around(" | ||
| + | // Dans le cas d'un Around, JoinPoint est en fait un ProceedingJoinPoint. | ||
| public Object twiceAsOld(ProceedingJoinPoint thisJoinPoint, | public Object twiceAsOld(ProceedingJoinPoint thisJoinPoint, | ||
| - | return thisJoinPoint.proceed(new Object[]{i*2}); | + | return thisJoinPoint.proceed(new Object[]{i*2}); |
| } | } | ||
| } | } | ||
| - | </code> | + | </file> |
| - | Séparation du point de coupure et de l' | + | Séparation du point de coupure et de l' |
| <code java> | <code java> | ||
| Ligne 142: | Ligne 180: | ||
| </ | </ | ||
| + | =====Mots clés disponibles dans un advice===== | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | Exemple avec '' | ||
| + | getArgs - 50 // Ici, un seul argument : un entier. | ||
| + | getKind - method-call | ||
| + | getTarget - test.C@30f39991 | ||
| + | getThis - null | ||
| + | getSignature - void test.C.incI(int) | ||
| + | toString - call(void test.C.incI(int)) | ||
| + | toLongString - call(void test.C.incI(int)) | ||
| + | toShortString - call(C.incI(..)) | ||
| + | getSourceLocation - C.java:18 | ||
| + | |||
| + | Exemple avec '' | ||
| + | getId - 0 | ||
| + | getKind - method-call | ||
| + | toLongString - call(void test.C.incI(int)) | ||
| + | toShortString - call(C.incI(..)) | ||
| + | getClass - class org.aspectj.runtime.reflect.JoinPointImpl$StaticPartImpl | ||
| + | getSignature - void test.C.incI(int) | ||
| + | getSourceLocation - C.java:18 | ||
| + | |||
| + | Exemple avec '' | ||
| + | getId - 1 | ||
| + | getKind - method-execution | ||
| + | toLongString - execution(public static void test.C.main(java.lang.String[])) | ||
| + | toShortString - execution(C.main(..)) | ||
| + | toString - execution(void test.C.main(String[])) | ||
| + | getSignature - void test.C.main(String[]) | ||
| + | getSourceLocation - C.java:16 | ||
| =====Accéder aux champs privés===== | =====Accéder aux champs privés===== | ||
| Mot clé : '' | Mot clé : '' | ||
| Ligne 161: | Ligne 232: | ||
| C'est niet. | C'est niet. | ||
| - | <note warning>Il est interdit de mélanger l' | + | <WRAP center round alert 60%> |
| + | Il est interdit de mélanger l' | ||
| + | |||
| + | < | ||
| + | </WRAP> | ||
| <file java C.java> | <file java C.java> | ||
| Ligne 470: | Ligne 545: | ||
| if (((C) joinPoint.getTarget()).i + x > MAX) | if (((C) joinPoint.getTarget()).i + x > MAX) | ||
| throw new RuntimeException(); | throw new RuntimeException(); | ||
| - | // En cas de méthode static, pas besion | + | // En cas de méthode static, pas besoin |
| joinPoint.proceed(new Object[] { x, joinPoint.getTarget() }); | joinPoint.proceed(new Object[] { x, joinPoint.getTarget() }); | ||
| } | } | ||
| Ligne 733: | Ligne 808: | ||
| } | } | ||
| </ | </ | ||
| - | <note>Il n'y a finalement pas de différence entre la méthode avec annotation et sans annotation, hormis que l' | + | |
| + | <WRAP center round info 60%> | ||
| + | Il n'y a finalement pas de différence entre la méthode avec annotation et sans annotation, hormis que l' | ||
| + | </WRAP> | ||
| =====Héritage et interface===== | =====Héritage et interface===== | ||
| <code java> | <code java> | ||
| Ligne 766: | Ligne 845: | ||
| } | } | ||
| </ | </ | ||
| + | |||
| + | =====Aspect à l' | ||
| + | Pour cela, il faut un JAR contenant l' | ||
| + | ====La classe ==== | ||
| + | Créez un '' | ||
| + | <file java C.java> | ||
| + | package classe; | ||
| + | |||
| + | public class C { | ||
| + | public int i = 0; | ||
| + | |||
| + | public void incI(int x) { | ||
| + | i = i + x; | ||
| + | } | ||
| + | |||
| + | static public void main(String[] arg) { | ||
| + | for (String string : arg) { | ||
| + | System.out.println(string); | ||
| + | } | ||
| + | C c = new C(); | ||
| + | c.incI(50); | ||
| + | c.incI(1000); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | Puis en console allez dans le dossier '' | ||
| + | <code bash> | ||
| + | jar cf C.jar classe | ||
| + | </ | ||
| + | |||
| + | ====L' | ||
| + | Créez un '' | ||
| + | <file java A.aj> | ||
| + | package aspects; | ||
| + | |||
| + | import org.aspectj.lang.ProceedingJoinPoint; | ||
| + | import org.aspectj.lang.annotation.Around; | ||
| + | import org.aspectj.lang.annotation.Aspect; | ||
| + | import org.aspectj.lang.annotation.Pointcut; | ||
| + | |||
| + | import classe.C; | ||
| + | |||
| + | // Les deux implémentations marchent. | ||
| + | |||
| + | public aspect A { | ||
| + | static final int MAX = 1000; | ||
| + | |||
| + | before(int x, C c): call(void C.incI(int)) && target(c) && args(x) { | ||
| + | System.out.println(" | ||
| + | if (c.i + x > MAX) | ||
| + | throw new RuntimeException(); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /* | ||
| + | @Aspect | ||
| + | public class A { | ||
| + | private static final int MAX = 1000; | ||
| + | |||
| + | @Around(" | ||
| + | // AutourDeCoupureIncI renvoie le même type que C.incI. | ||
| + | public void AutourDeCoupureIncI(ProceedingJoinPoint joinPoint, int x) throws Throwable { | ||
| + | System.out.println(" | ||
| + | if (((C) joinPoint.getTarget()).i + x > MAX) | ||
| + | throw new RuntimeException(); | ||
| + | |||
| + | joinPoint.proceed(new Object[] { x }); | ||
| + | System.out.println(" | ||
| + | } | ||
| + | } | ||
| + | */ | ||
| + | </ | ||
| + | La classe dépendant de C, il ne faut pas oublie d' | ||
| + | |||
| + | Puis en console allez dans le dossier '' | ||
| + | <code bash> | ||
| + | jar cf A.jar aspects | ||
| + | </ | ||
| + | |||
| + | ====La classe exécutrice==== | ||
| + | Créez un '' | ||
| + | <file java Main.java> | ||
| + | package main; | ||
| + | |||
| + | import java.io.IOException; | ||
| + | import java.lang.reflect.InvocationTargetException; | ||
| + | import java.lang.reflect.Method; | ||
| + | import java.net.URL; | ||
| + | |||
| + | import org.aspectj.weaver.loadtime.WeavingURLClassLoader; | ||
| + | |||
| + | public class Main { | ||
| + | static public void main(String[] arg) throws ClassNotFoundException, | ||
| + | SecurityException, | ||
| + | try (WeavingURLClassLoader weaving = new WeavingURLClassLoader( | ||
| + | new URL[] { new URL(" | ||
| + | new URL[] { new URL(" | ||
| + | Thread.currentThread().getContextClassLoader())) { | ||
| + | Thread.currentThread().setContextClassLoader(weaving); | ||
| + | |||
| + | Class<?> | ||
| + | |||
| + | Method mainMethod = classC.getMethod(" | ||
| + | |||
| + | mainMethod.invoke(null, | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Pensez à ajouter le jar '' | ||
| + | |||
| + | ====Exécution==== | ||
| + | Start | ||
| + | Before | ||
| + | Before | ||
| + | Exception in thread " | ||
| + | at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) | ||
| + | at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java: | ||
| + | at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java: | ||
| + | at java.lang.reflect.Method.invoke(Method.java: | ||
| + | at main.Main.main(Main.java: | ||
| + | Caused by: java.lang.RuntimeException | ||
| + | at aspects.A.ajc$before$aspects_A$1$ff7f72c0(A.aj: | ||
| + | at classe.C.main(C.java: | ||
| + | ... 5 more | ||
| + | |||
| + | ====Commentaires==== | ||
| + | Il est impératif que le projet '' | ||
| + | |||
| + | [[https:// | ||
lang/java/aspectj.1481756717.txt.gz · Dernière modification : de root
