2010-05-04 12 views
16

que necesitan para crear un aspecto con un punto de corte coincide con un método si:métodos que coinciden con los parámetros anotados pointcut

  • es público
  • su clase se anota con @Controller (último no lo hace)
  • Uno de sus parámetros (puede tener muchos) se anota con @MyParamAnnotation.

Creo que las dos primeras condiciones son fáciles, pero no sé si es posible lograr el tercero con Spring. Si no es así, tal vez pueda cambiar en:

  • uno de sus parámetros es una instancia del tipo com.me.MyType (o pone en práctica alguna de las interfaces)

¿Cree que es posible ¿lograr esto? ¿Y el rendimiento será bueno?

Gracias

EDITAR: Un ejemplo de un método de emparejamiento. Como puede ver, MyMethod no está anotado (pero puede ser).

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

EDITAR: La solución finalmente he utilizado, basado en las respuestas @Espen. Como puede ver, cambié un poco mis condiciones: la clase en realidad no necesita ser un @Controller.

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

Respuesta

19

¡Era un problema interesante, así que creé una pequeña aplicación de muestra para resolver el caso! (Y mejorado con retroalimentación de Sinuhé después.)

He creado una clase DemoController que debería funcionar como un ejemplo para el aspecto:

@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) { 
    } 
} 

El aspecto que agregará un punto de combinación en los tres primeros métodos , pero no el último método en el que el parámetro no está anotado 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"); 
    } 
} 

el primer punto de corte creará un joinpoint sobre todos los métodos dentro de clases marcados con @Controller.

El segundo punto de corte añadirá un joinpoint cuando se cumplan las siguientes condiciones:

  • método público
  • primera * es un comodín para cada tipo de retorno.
  • segundo * es un comodín para todos los métodos en todas las clases.
  • (.., coincide con cero a muchos parámetros de cualquier tipo antes del parámetro anotado.
  • @aspects.MyParamAnnotation (*), coincide con un parámetro anotado con la anotación dada.
  • ..) coincide con cero a muchos parámetros de cualquier tipo después del parámetro anotado.

Finalmente, el consejo @Before aconseja todos los métodos donde se satisfacen todas las condiciones en ambos puntos de corte.

¡El punto de corte funciona tanto con AspectJ como con Spring AOP!

Cuando se trata de rendimiento. La sobrecarga es pequeña, especialmente con AspectJ que teje el tiempo de compilación o el tiempo de carga.

+0

Se ve bien, pero no es exactamente lo que estoy buscando. Edité mi pregunta para ser más preciso. Gracias. – sinuhepop

+1

He encontrado un método para simplificarlo. Edité mi pregunta, ¡pero todos los créditos sobre ti! Gracias. – sinuhepop

+0

¡Buena edición! Me alegra verte como este tipo de preguntas;) – sinuhepop

Cuestiones relacionadas