java - settitle - set name to jframe
Métodos de coincidencia de corte de puntos con parámetros anotados (1)
Necesito crear un aspecto con un punto de corte que coincida con un método si:
- Es público
- Su clase está anotada con @Controller (Finalmente 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 la tercera con Spring. Si no lo es, tal vez pueda cambiarlo por:
- Uno de sus parámetros es una instancia de tipo com.me.MyType (o implementa alguna interfaz)
¿Crees que es posible lograr esto? ¿Y el rendimiento será bueno?
Gracias
EDITAR : Un ejemplo de un método de coincidencia. Como puede ver, MyMethod no está anotado (pero puede estarlo).
@Controller
public class MyClass {
public void MyMethod (String arg0, @MyParamAnnotation Object arg1, Long arg3) {
...
}
}
EDITAR : La solución que finalmente utilicé, basada en las respuestas de @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 {
...
}
Fue un problema interesante, ¡así que creé una pequeña aplicación de muestra para resolver el caso! (Y lo mejoré con la retroalimentación de Sinuhe 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 unión en los primeros tres métodos, pero no el último método donde el parámetro no se anota 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 punto de unión en todos los métodos dentro de las clases marcadas con @Controller
.
El segundo punto de corte agregará un punto de unión cuando se cumplan las siguientes condiciones:
- método público
- first
*
es un comodín para cada tipo de devolución. - second
*
es un comodín para todos los métodos en todas las clases. -
(..,
coincide con cero con muchos parámetros de cualquier tipo antes del parámetro anotado. -
@aspects.MyParamAnnotation (*),
coincide con un parámetro anotado con la anotación dada. -
..)
empareja cero con muchos parámetros de cualquier tipo después del parámetro anotado.
Finalmente, el consejo de @Before
informa sobre todos los métodos en los que se cumplen todas las condiciones en ambos puntos.
El punto de corte funciona con AspectJ y Spring AOP!
Cuando se trata de rendimiento. La sobrecarga es pequeña, especialmente con AspectJ que hace el tejido en tiempo de compilación o tiempo de carga.