2010-08-17 6 views
3

il est commode pour AOP (par exemple AspectJ, SpringAOP) pour traiter (conseiller) préoccupations incisée à pointcuts autour des méthodes ci-dessous,préoccupations Crosscut au milieu des méthodes

code "sandwich"

methodA { 
    crosscut code 
    user code A 
    crosscut code 
} 

methodB { 
    crosscut code 
    user code B 
    crosscut code 
} 

Est AOP apte à recouper les préoccupations chevauchées au code utilisateur ci-dessous? Comment?

Code

methodX { 
    user code x1 
    crosscut code 

    user code x2 
    crosscut code 
} 

methodY { 

    user code y1 
    crosscut code 

    user code y2 
    crosscut code 
} 

"Spaghetti" Merci!

Répondre

4

Spring AOP ne sera pas utile, car elle ne comprend que l'exécution pointcut().

AspectJ comprend beaucoup plus pointcuts, y compris le withincode() construire, qui ressemble à ce que vous voulez:

withincode(* YourClass.methodX(. .)) 

cela vous permet de conseiller tous les points de jonction dans une méthode donnée exection

Lire AspectJ in Action Pour plus d'informations, c'est un très bon livre sur AspectJ et Spring AOP.


EDIT:

ici est un exemple de code:

package com.dummy.aspectj; 

import java.util.Arrays; 
import java.util.Collections; 

public class DummyClass{ 

    public static void main(final String[] args){ 
     System.out.println(Arrays.asList("One", Collections.singleton("Two"))); 
     System.out.println("Enough?"); 
    } 

} 

package com.dummy.aspectj; 

import java.util.Arrays; 

public aspect DummyAspect{ 

    pointcut callWithinMain() : 
     withincode(* com.dummy.aspectj.DummyClass.main(..)) // anything inside DummyClass.main 
     && call(* *.*(..));         // but only method calls 

    before() : callWithinMain() { 
     System.out.println("\n***************************************************"); 
     System.out.println("** Calling:\n**\t" 
      + thisJoinPointStaticPart.getSignature() 
      + "\n** with arguments:\n**\t " 
      + Arrays.deepToString(thisJoinPoint.getArgs())); 
     System.out.println("***************************************************\n"); 
    } 

} 

exécutant le DummyClass d'Eclipse/AJDT génère cette sortie:

*************************************************** 
** Calling: 
** Set java.util.Collections.singleton(Object) 
** with arguments: 
** [Two] 
*************************************************** 


*************************************************** 
** Calling: 
** List java.util.Arrays.asList(Object[]) 
** with arguments: 
** [[One, [Two]]] 
*************************************************** 


*************************************************** 
** Calling: 
** void java.io.PrintStream.println(Object) 
** with arguments: 
** [[One, [Two]]] 
*************************************************** 

[One, [Two]] 

*************************************************** 
** Calling: 
** void java.io.PrintStream.println(String) 
** with arguments: 
** [Enough?] 
*************************************************** 

Enough? 
+0

Avez-vous un exemple pratique pour le placer ici? Merci pour l'illumination! – sof

+0

voir ma mise à jour post pour un exemple de code –

+0

Oh! assez pour la digestion. – sof

2

Bien que certaines implémentations AOP puissent vous permettre de faire cela, cela pourrait indiquer la nécessité de refactoriser ces méthodes en méthodes plus composées car elles pourraient en faire trop si l'on a besoin de transcender les préoccupations au milieu des méthodes . Cela vous donnerait ceci:

methodX 
{ 
    usercodemethod1(); 
    usercodemethod2(); 
} 

usercodemethod1 
{ 
    user code x1 
    crosscut code 
} 

usercodemethod2 
{ 
    user code x2 
    crosscut code 
} 
+0

Nous refactoring en termes de la meilleure pratique. Le refactoring à AOP est-il une bonne pratique en général? Si ce n'est pas le cas, nous admettrons que l'AOP est susceptible de restreindre assez les domaines de problèmes, par ex. feu vert à la démarcation des transactions, mais rouge à la journalisation. – sof

+0

Je ne dirais pas qu'il faut refactoriser juste pour répondre à AOP, mais comme mentionné par @seanizer, le printemps ne va pas aider avec cela, donc cela pourrait être votre meilleur pari si vous allez cette route - tout proxy (runtime) AOP basé ne prendra normalement pas en charge le code de tissage au milieu d'une méthode – saret

+0

@saret: cela ne fonctionnera pas avec un proxy basé sur aop. quand methodX appelle usercodemethod1 (en supposant qu'ils sont dans la même classe), il n'appelle pas le proxy mais la classe réelle (vous êtes déjà dans le proxy), donc les conseils n'ont pas la possibilité de s'exécuter. La seule façon d'y parvenir est donc de rendre le workflow complet accessible de l'extérieur (client appelle usercodemethod1, puis usercodemethod2 etc.), ce qui viole massivement le principe DRY. –