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/12 23:57] – Ajout d'un commentaire pour l'utilisation combinée des annotations et sans annotation 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===== | ||
+ | Sans annotation | ||
<code java> | <code java> | ||
public aspect Log { | public aspect Log { | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Avec annotation | ||
+ | <code java> | ||
+ | import org.aspectj.lang.annotation.Aspect; | ||
+ | |||
+ | @Aspect | ||
+ | public class Log { | ||
} | } | ||
</ | </ | ||
=====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 39: | 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 54: | 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 89: | 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 105: | 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 132: | 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é : '' | ||
- | |||
- | <note warning> | ||
<code java> | <code java> | ||
Ligne 150: | Ligne 229: | ||
</ | </ | ||
+ | =====Mélange avec annotation et sans annotation===== | ||
+ | C'est niet. | ||
+ | |||
+ | <WRAP center round alert 60%> | ||
+ | Il est interdit de mélanger l' | ||
+ | |||
+ | < | ||
+ | </ | ||
+ | |||
+ | <file java C.java> | ||
+ | public class C { | ||
+ | public int i = 0; | ||
+ | |||
+ | void incI(int x) { | ||
+ | System.out.println(i); | ||
+ | i = i + x; | ||
+ | } | ||
+ | |||
+ | static public void main(String[] args) { | ||
+ | C c = new C(); | ||
+ | c.incI(50); | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <file java A.aj> | ||
+ | import org.aspectj.lang.annotation.Around; | ||
+ | //import org.aspectj.lang.annotation.Aspect; | ||
+ | import org.aspectj.lang.annotation.Pointcut; | ||
+ | |||
+ | //@Aspect | ||
+ | public aspect A { | ||
+ | static final int MAX = 1000; | ||
+ | |||
+ | @Pointcut(" | ||
+ | private void CoupureIncI(int x, C c) { | ||
+ | } | ||
+ | |||
+ | @Around(" | ||
+ | public void incIA(int x, C c) { | ||
+ | if (c.i + x > MAX) | ||
+ | throw new RuntimeException(); | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Résultat à l' | ||
+ | Error: A JNI error has occurred, please check your installation and try again | ||
+ | Exception in thread " | ||
+ | Exception Details: | ||
+ | Location: | ||
+ | test/ | ||
+ | Reason: | ||
+ | Type ' | ||
+ | Current Frame: | ||
+ | bci: @21 | ||
+ | flags: { } | ||
+ | locals: { ' | ||
+ | stack: { ' | ||
+ | Bytecode: | ||
+ | 0x0000000: bb00 0159 b700 234c 2b10 323d 4e2d 1cb8 | ||
+ | 0x0000010: 0036 1c2d 01b8 003a b1 | ||
+ | | ||
+ | at java.lang.Class.getDeclaredMethods0(Native Method) | ||
+ | at java.lang.Class.privateGetDeclaredMethods(Class.java: | ||
+ | at java.lang.Class.privateGetMethodRecursive(Class.java: | ||
+ | at java.lang.Class.getMethod0(Class.java: | ||
+ | at java.lang.Class.getMethod(Class.java: | ||
+ | at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java: | ||
+ | at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java: | ||
+ | |||
=====AspectJ en interne===== | =====AspectJ en interne===== | ||
Le compilateur ajc utilise les points de coupe et les advices pour scanner le code source et trouver toutes les méthodes appelantes et les encadre avant par un appel des méthodes '' | Le compilateur ajc utilise les points de coupe et les advices pour scanner le code source et trouver toutes les méthodes appelantes et les encadre avant par un appel des méthodes '' | ||
- | Code java : | + | ====Exemple avec before==== |
+ | ===Code source=== | ||
<file java C.java> | <file java C.java> | ||
public class C { | public class C { | ||
Ligne 181: | Ligne 332: | ||
</ | </ | ||
- | Version décompilée avec l' | + | ===Version décompilée avec l' |
<file java C.java> | <file java C.java> | ||
public class C | public class C | ||
Ligne 205: | Ligne 356: | ||
public static void main(String[] arg) | public static void main(String[] arg) | ||
{ | { | ||
- | // Le code before entoure | + | // Le code before entoure |
C c = new C(); | C c = new C(); | ||
int j = 50;C localC1 = c; | int j = 50;C localC1 = c; | ||
Ligne 260: | Ligne 411: | ||
</ | </ | ||
- | Version décompilée avec l' | + | ===Version décompilée avec l' |
<file java C.java> | <file java C.java> | ||
public class C | public class C | ||
Ligne 278: | Ligne 429: | ||
void incI(int x) | void incI(int x) | ||
{ | { | ||
- | // Le code before entoure la méthode surveillée | + | // Le code before entoure |
int j = x; | int j = x; | ||
} | } | ||
Ligne 337: | Ligne 488: | ||
} | } | ||
</ | </ | ||
+ | |||
+ | ====Exemple avec around==== | ||
+ | ===Code source=== | ||
+ | <file java C.java> | ||
+ | public class C { | ||
+ | public int i = 0; | ||
+ | |||
+ | void incI(int x) { | ||
+ | System.out.println(" | ||
+ | i = i + x; | ||
+ | } | ||
+ | |||
+ | void incI() { | ||
+ | System.out.println(" | ||
+ | i = i + 1; | ||
+ | } | ||
+ | |||
+ | static public void main(String[] arg) { | ||
+ | C c = new C(); | ||
+ | c.incI(50); | ||
+ | c.incI(500); | ||
+ | c.incI(1500); | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <file java A.aj> | ||
+ | public privileged aspect A { | ||
+ | private static final int MAX = 1000; | ||
+ | |||
+ | void around(C c, int x): call(void C.incI(int)) && target(c) && args(x) { | ||
+ | if (c.i + x > MAX) | ||
+ | throw new RuntimeException(); | ||
+ | proceed(c, x); | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <file java A2.aj> | ||
+ | import org.aspectj.lang.ProceedingJoinPoint; | ||
+ | import org.aspectj.lang.annotation.Around; | ||
+ | import org.aspectj.lang.annotation.Aspect; | ||
+ | import org.aspectj.lang.annotation.Pointcut; | ||
+ | |||
+ | @Aspect | ||
+ | public class A2 { | ||
+ | private static final int MAX = 1000; | ||
+ | |||
+ | @Pointcut(" | ||
+ | private void CoupureIncI(int x) { | ||
+ | } | ||
+ | |||
+ | @Around(" | ||
+ | // AutourDeCoupureIncI renvoie le même type que C.incI. | ||
+ | public void AutourDeCoupureIncI(ProceedingJoinPoint joinPoint, int x) throws Throwable { | ||
+ | if (((C) joinPoint.getTarget()).i + x > MAX) | ||
+ | throw new RuntimeException(); | ||
+ | // En cas de méthode static, pas besoin de joinPoint.getTarget(). | ||
+ | joinPoint.proceed(new Object[] { x, joinPoint.getTarget() }); | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===Version décompilée avec l' | ||
+ | <file java C.java> | ||
+ | import java.io.PrintStream; | ||
+ | import org.aspectj.runtime.internal.AroundClosure; | ||
+ | |||
+ | public class C | ||
+ | { | ||
+ | public int i = 0; | ||
+ | | ||
+ | void incI(int x) | ||
+ | { | ||
+ | System.out.println(" | ||
+ | this.i += x; | ||
+ | } | ||
+ | | ||
+ | private static final void incI_aroundBody1$advice(C target, int x, A ajc$aspectInstance, | ||
+ | { | ||
+ | if (c.i + x > 1000) { | ||
+ | throw new RuntimeException(); | ||
+ | } | ||
+ | AroundClosure localAroundClosure = ajc$aroundClosure; | ||
+ | } | ||
+ | | ||
+ | private static final void incI_aroundBody3$advice(C target, int x, A ajc$aspectInstance, | ||
+ | { | ||
+ | if (c.i + x > 1000) { | ||
+ | throw new RuntimeException(); | ||
+ | } | ||
+ | AroundClosure localAroundClosure = ajc$aroundClosure; | ||
+ | } | ||
+ | | ||
+ | private static final void incI_aroundBody5$advice(C target, int x, A ajc$aspectInstance, | ||
+ | { | ||
+ | if (c.i + x > 1000) { | ||
+ | throw new RuntimeException(); | ||
+ | } | ||
+ | AroundClosure localAroundClosure = ajc$aroundClosure; | ||
+ | } | ||
+ | | ||
+ | void incI() | ||
+ | { | ||
+ | System.out.println(" | ||
+ | this.i += 1; | ||
+ | } | ||
+ | | ||
+ | private static final void incI_aroundBody0(C paramC, int paramInt) | ||
+ | { | ||
+ | paramC.incI(paramInt); | ||
+ | } | ||
+ | | ||
+ | private static final void incI_aroundBody2(C paramC, int paramInt) | ||
+ | { | ||
+ | paramC.incI(paramInt); | ||
+ | } | ||
+ | | ||
+ | public static void main(String[] arg) | ||
+ | { | ||
+ | C c = new C(); | ||
+ | int j = 50;C localC1 = c; | ||
+ | int k = 500;C localC2 = c; | ||
+ | int m = 1500;C localC3 = c; | ||
+ | } | ||
+ | | ||
+ | private static final void incI_aroundBody4(C paramC, int paramInt) | ||
+ | { | ||
+ | paramC.incI(paramInt); | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <file java A.aj> | ||
+ | import org.aspectj.internal.lang.annotation.ajcPrivileged; | ||
+ | import org.aspectj.lang.NoAspectBoundException; | ||
+ | import org.aspectj.lang.annotation.Around; | ||
+ | import org.aspectj.lang.annotation.Aspect; | ||
+ | import org.aspectj.runtime.internal.AroundClosure; | ||
+ | |||
+ | @Aspect | ||
+ | @ajcPrivileged | ||
+ | public class A | ||
+ | { | ||
+ | private static final int MAX = 1000; | ||
+ | | ||
+ | public static A aspectOf() | ||
+ | { | ||
+ | if (ajc$perSingletonInstance == null) { | ||
+ | throw new NoAspectBoundException(" | ||
+ | } | ||
+ | return ajc$perSingletonInstance; | ||
+ | } | ||
+ | | ||
+ | public static boolean hasAspect() | ||
+ | { | ||
+ | return ajc$perSingletonInstance != null; | ||
+ | } | ||
+ | | ||
+ | static | ||
+ | { | ||
+ | try | ||
+ | { | ||
+ | | ||
+ | } | ||
+ | catch (Throwable localThrowable) | ||
+ | { | ||
+ | ajc$initFailureCause = localThrowable; | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | @Around(value=" | ||
+ | public void ajc$around$test_A$1$ff7f72c0(C c, int x, AroundClosure ajc$aroundClosure) | ||
+ | { | ||
+ | if (c.i + x > 1000) { | ||
+ | throw new RuntimeException(); | ||
+ | } | ||
+ | ajc$around$test_A$1$ff7f72c0proceed(c, | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===Version décompilée avec l' | ||
+ | <file java C.java> | ||
+ | import java.io.PrintStream; | ||
+ | import org.aspectj.lang.JoinPoint; | ||
+ | import org.aspectj.lang.JoinPoint.StaticPart; | ||
+ | import org.aspectj.lang.ProceedingJoinPoint; | ||
+ | import org.aspectj.runtime.internal.Conversions; | ||
+ | import org.aspectj.runtime.reflect.Factory; | ||
+ | |||
+ | public class C | ||
+ | { | ||
+ | private static void ajc$preClinit() | ||
+ | { | ||
+ | Factory localFactory = new Factory(" | ||
+ | } | ||
+ | | ||
+ | public int i = 0; | ||
+ | private static final JoinPoint.StaticPart ajc$tjp_0; | ||
+ | private static final JoinPoint.StaticPart ajc$tjp_1; | ||
+ | private static final JoinPoint.StaticPart ajc$tjp_2; | ||
+ | | ||
+ | void incI(int x) | ||
+ | { | ||
+ | System.out.println(" | ||
+ | this.i += x; | ||
+ | } | ||
+ | | ||
+ | void incI() | ||
+ | { | ||
+ | System.out.println(" | ||
+ | this.i += 1; | ||
+ | } | ||
+ | | ||
+ | private static final void incI_aroundBody0(C paramC, int paramInt, JoinPoint paramJoinPoint) | ||
+ | { | ||
+ | paramC.incI(paramInt); | ||
+ | } | ||
+ | | ||
+ | private static final void incI_aroundBody2(C paramC, int paramInt, JoinPoint paramJoinPoint) | ||
+ | { | ||
+ | paramC.incI(paramInt); | ||
+ | } | ||
+ | | ||
+ | public static void main(String[] arg) | ||
+ | { | ||
+ | C c = new C(); | ||
+ | int j = 50;C localC1 = c;JoinPoint localJoinPoint1 = Factory.makeJP(ajc$tjp_0, | ||
+ | int k = 500;C localC2 = c;JoinPoint localJoinPoint2 = Factory.makeJP(ajc$tjp_1, | ||
+ | int m = 1500;C localC3 = c;JoinPoint localJoinPoint3 = Factory.makeJP(ajc$tjp_2, | ||
+ | } | ||
+ | | ||
+ | private static final void incI_aroundBody4(C paramC, int paramInt, JoinPoint paramJoinPoint) | ||
+ | { | ||
+ | paramC.incI(paramInt); | ||
+ | } | ||
+ | | ||
+ | private static final void incI_aroundBody1$advice(C target, int x, JoinPoint thisJoinPoint, | ||
+ | { | ||
+ | if (((C)joinPoint.getTarget()).i + x > 1000) { | ||
+ | throw new RuntimeException(); | ||
+ | } | ||
+ | Object[] arrayOfObject = { Integer.valueOf(x), | ||
+ | } | ||
+ | | ||
+ | private static final void incI_aroundBody3$advice(C target, int x, JoinPoint thisJoinPoint, | ||
+ | { | ||
+ | if (((C)joinPoint.getTarget()).i + x > 1000) { | ||
+ | throw new RuntimeException(); | ||
+ | } | ||
+ | Object[] arrayOfObject = { Integer.valueOf(x), | ||
+ | } | ||
+ | | ||
+ | private static final void incI_aroundBody5$advice(C target, int x, JoinPoint thisJoinPoint, | ||
+ | { | ||
+ | if (((C)joinPoint.getTarget()).i + x > 1000) { | ||
+ | throw new RuntimeException(); | ||
+ | } | ||
+ | Object[] arrayOfObject = { Integer.valueOf(x), | ||
+ | } | ||
+ | | ||
+ | static {} | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <file java A2.aj> | ||
+ | import org.aspectj.lang.NoAspectBoundException; | ||
+ | import org.aspectj.lang.ProceedingJoinPoint; | ||
+ | import org.aspectj.lang.annotation.Around; | ||
+ | import org.aspectj.lang.annotation.Aspect; | ||
+ | |||
+ | @Aspect | ||
+ | public class A2 | ||
+ | { | ||
+ | private static final int MAX = 1000; | ||
+ | private static Throwable ajc$initFailureCause; | ||
+ | public static final A2 ajc$perSingletonInstance; | ||
+ | | ||
+ | static | ||
+ | { | ||
+ | try | ||
+ | { | ||
+ | ajc$postClinit(); | ||
+ | } | ||
+ | catch (Throwable localThrowable) | ||
+ | { | ||
+ | ajc$initFailureCause = localThrowable; | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | private static void ajc$postClinit() | ||
+ | { | ||
+ | ajc$perSingletonInstance = new A2(); | ||
+ | } | ||
+ | | ||
+ | public static boolean hasAspect() | ||
+ | { | ||
+ | return ajc$perSingletonInstance != null; | ||
+ | } | ||
+ | | ||
+ | public static A2 aspectOf() | ||
+ | { | ||
+ | if (ajc$perSingletonInstance == null) { | ||
+ | throw new NoAspectBoundException(" | ||
+ | } | ||
+ | return ajc$perSingletonInstance; | ||
+ | } | ||
+ | | ||
+ | @Around(" | ||
+ | public void AutourDeCoupureIncI(ProceedingJoinPoint joinPoint, int x) | ||
+ | throws Throwable | ||
+ | { | ||
+ | if (((C)joinPoint.getTarget()).i + x > 1000) { | ||
+ | throw new RuntimeException(); | ||
+ | } | ||
+ | joinPoint.proceed(new Object[] { Integer.valueOf(x), | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <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' | ||
+ | </ | ||
+ | |||
=====Héritage et interface===== | =====Héritage et interface===== | ||
<code java> | <code java> | ||
Ligne 369: | 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.1481583456.txt.gz · Dernière modification : 2016/12/12 23:57 de root