145 votes

@AspectJ pointcut pour toutes les méthodes d'une classe avec une annotation spécifique

Je souhaite surveiller toutes les méthodes publiques de toutes les classes avec une annotation spécifiée (par exemple, @Monitor) (note: l'annotation est au niveau de la classe). Quel pourrait être un point possible pour cela? Remarque: J'utilise le style Spring AOP de @AspectJ.

191voto

Espen Points 5898

Vous devez combiner un type coupe transverse (pointcut) avec une méthode de coupe transverse (pointcut).

Ces pointcuts va faire le travail pour trouver toutes les méthodes publiques à l'intérieur d'une classe marquée avec un @Moniteur annotation:

@Pointcut("within(@org.rejeev.Monitor *)")
public void beanAnnotatedWithMonitor() {}

@Pointcut("execution(public * *(..))")
public void publicMethod() {}

@Pointcut("publicMethod() && beanAnnotatedWithMonitor()")
public void publicMethodInsideAClassMarkedWithAtMonitor() {}

Les conseils de la dernière coupe transverse (pointcut) qui combine les deux premiers et vous avez terminé!

Si vous êtes intéressé, j'ai écrit une feuille de triche avec @AspectJ style ici avec un correspondant document de l'exemple ici.

69voto

Alex Points 1864

À l'aide d'annotations, comme décrit dans la question.

Annotation: @Monitor

Annotation sur la classe, app/PagesController.java:

package app;
@Controller
@Monitor
public class PagesController {
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public @ResponseBody String home() {
        return "w00t!";
    }
}

Annotation sur la méthode, app/PagesController.java:

package app;
@Controller
public class PagesController {
    @Monitor
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public @ResponseBody String home() {
        return "w00t!";
    }
}

Annotations personnalisées, app/Monitor.java:

package app;
@Component
@Target(value = {ElementType.METHOD, ElementType.TYPE})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Monitor {
}

Aspect de l'annotation, app/MonitorAspect.java:

package app;
@Component
@Aspect
public class MonitorAspect {
    @Before(value = "@within(app.Monitor) || @annotation(app.Monitor)")
    public void before(JoinPoint joinPoint) throws Throwable {
        LogFactory.getLog(MonitorAspect.class).info("monitor.before, class: " + joinPoint.getSignature().getDeclaringType().getSimpleName() + ", method: " + joinPoint.getSignature().getName());
    }

    @After(value = "@within(app.Monitor) || @annotation(app.Monitor)")
    public void after(JoinPoint joinPoint) throws Throwable {
        LogFactory.getLog(MonitorAspect.class).info("monitor.after, class: " + joinPoint.getSignature().getDeclaringType().getSimpleName() + ", method: " + joinPoint.getSignature().getName());
    }
}

Activer AspectJ, servlet-context.xml:

<aop:aspectj-autoproxy />

Inclure AspectJ bibliothèques, pom.xml:

<artifactId>spring-aop</artifactId>
<artifactId>aspectjrt</artifactId>
<artifactId>aspectjweaver</artifactId>
<artifactId>cglib</artifactId>

16voto

Bozho Points 273663

Quelque chose comme ca:

 @Before("execution(* com.yourpackage..*.*(..))")
public void monitor(JoinPoint jp) {
    if (jp.getTarget().getClass().isAnnotationPresent(Monitor.class)) {
       // perform the monitoring actions
    }
}
 

Notez que vous ne devez avoir aucun autre conseil sur la même classe avant celle-ci, car les annotations seront perdues après le remplacement du proxy.

6voto

marcocast Points 86

cela devrait suffire à marquer votre méthode d'aspect comme ceci:

 @After("@annotation(com.marcot.CommitTransaction)")
    public void after() {
 

Jetez un coup d'oeil à ceci pour un guide étape par étape à ce sujet.

3voto

Shekhar Points 1552

Vous pouvez également définir le pointcut comme

 public pointcut publicMethodInsideAClassMarkedWithAtMonitor() : execution(public * (@Monitor *).*(..));
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X