2010-05-04 11 views
16

ho bisogno di creare un aspetto con una pointcut corrispondenza di un metodo se:pointcut metodi di corrispondenza con i parametri annotati

  • è pubblica
  • La sua classe è annotata con @Controller (finalmente non lo fa)
  • Uno dei suoi parametri (può avere molti) è annotato con @MyParamAnnotation.

Penso che le prime due condizioni siano facili, ma non so se è possibile realizzare il terzo con Spring. Se non lo è, forse posso trasformarla in:

  • Uno dei suoi parametri è un'istanza di tipo com.me.MyType (o implementa alcune interfaccia)

Pensi che è possibile raggiungere questo? E le prestazioni andranno bene?

Grazie

EDIT: Un esempio di un metodo di corrispondenza. Come puoi vedere, MyMethod non è annotato (ma può essere).

@Controller 
public class MyClass { 
    public void MyMethod (String arg0, @MyParamAnnotation Object arg1, Long arg3) { 
     ... 
    } 
} 

EDIT: La soluzione alla fine ho usato, in base alle risposte @Espen. Come puoi vedere, ho cambiato un po 'le mie condizioni: la classe in realtà non ha bisogno di essere un @Controller.

@Around("execution(public * * (.., @SessionInject (*), ..))") 
public void methodAround(JoinPoint joinPoint) throws Exception { 
    ... 
} 

risposta

19

È stato un problema interessante, quindi ho creato una piccola applicazione di esempio per risolvere il caso! (E migliorato con un feedback di Sinuhe dopo.)

Ho creato una classe DemoController che dovrebbe funzionare come un esempio per l'aspetto:

@Controller 
public class DemoController { 

    public void soSomething(String s, @MyParamAnnotation Double d, Integer i) { 
    } 

    public void doSomething(String s, long l, @MyParamAnnotation int i) { 
    } 

    public void doSomething(@MyParamAnnotation String s) { 
    } 

    public void doSomething(long l) { 
    } 
} 

L'aspetto che aggiungerà un punto di join sui primi tre metodi , ma non l'ultimo metodo in cui il parametro non è annotata con @MyParamAnnotation:

@Aspect 
public class ParameterAspect { 

    @Pointcut("within(@org.springframework.stereotype.Controller *)") 
    public void beanAnnotatedWithAtController() { 
    } 

    @Pointcut("execution(public * *(.., @aspects.MyParamAnnotation (*), ..))") 
    public void methodWithAnnotationOnAtLeastOneParameter() { 
    } 

    @Before("beanAnnotatedWithAtController() " 
      + "&& methodWithAnnotationOnAtLeastOneParameter()") 
    public void beforeMethod() {  
     System.out.println("At least one of the parameters are " 
        + "annotated with @MyParamAnnotation"); 
    } 
} 

la prima pointcut creerà un joinpoint su tutti i metodi all'interno delle classi contrassegnati con @Controller.

La seconda pointcut aggiungerà una joinpoint quando sono soddisfatte le seguenti condizioni:

  • metodo pubblico
  • prima * è un carattere jolly per ogni tipo di ritorno.
  • secondo * è un jolly per tutti i metodi in tutte le classi.
  • (.., corrisponde a zero a molti parametri di qualsiasi tipo prima del parametro annotato.
  • @aspects.MyParamAnnotation (*), corrisponde a un parametro annotato con l'annotazione specificata.
  • ..) corrisponde a zero a molti parametri di qualsiasi tipo dopo il parametro annotato.

Infine, il consiglio @Before consiglia tutti i metodi in cui sono soddisfatte tutte le condizioni in entrambi i collegamenti.

Il pointcut funziona con AspectJ e Spring AOP!

Quando si tratta di prestazioni. Il sovraccarico è piccolo, specialmente con AspectJ che fa la tessitura in fase di compilazione o di caricamento.

+0

Sembra buono, ma non è esattamente quello che sto cercando. Ho modificato la mia domanda per essere più preciso. Grazie. – sinuhepop

+1

Ho trovato un metodo per semplificarlo. Ho modificato la mia domanda, ma tutti i crediti su di te! Grazie. – sinuhepop

+0

Buona modifica! Sono contento di vederti come questo tipo di domande;) – sinuhepop

Problemi correlati