具有特定注释的类的所有方法的@AspectJ切入点

Rej*_*ran 117 java aop aspectj spring-aop

我想监视具有指定注释的所有类的所有公共方法(比如@Monitor)(注意:注释在类级别).什么可能是一个可能的切入点?注意:我使用的是@AspectJ样式的Spring AOP.

Esp*_*pen 151

您应该将类​​型切入点与方法切入点组合在一起.

这些切入点将用于查找标有@Monitor注释的类中的所有公共方法:

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

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

@Pointcut("publicMethod() && beanAnnotatedWithMonitor()")
public void publicMethodInsideAClassMarkedWithAtMonitor() {}
Run Code Online (Sandbox Code Playgroud)

建议结合前两个切入点的最后一个切入点,你已经完成了!

如果您有兴趣,我在这里写了一个带@AspectJ样式的备忘单,并附上相应的示例文档.


Ale*_*lex 55

使用注释,如问题中所述.

注解: @Monitor

关于类的注释app/PagesController.java:

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

方法注释app/PagesController.java:

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

自定义注释,app/Monitor.java:

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

注释的方面,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());
    }
}
Run Code Online (Sandbox Code Playgroud)

启用AspectJ的,servlet-context.xml:

<aop:aspectj-autoproxy />
Run Code Online (Sandbox Code Playgroud)

包括AspectJ库,pom.xml:

<artifactId>spring-aop</artifactId>
<artifactId>aspectjrt</artifactId>
<artifactId>aspectjweaver</artifactId>
<artifactId>cglib</artifactId>
Run Code Online (Sandbox Code Playgroud)

  • `@Component`注释使得Spring将使用AspectJ IoC/DI面向方面的系统进行编译.我不知道如何区别对待.http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/aop.html (2认同)

Boz*_*zho 13

像这样的东西:

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

请注意,此类之前,您不能对同一个类有任何其他建议,因为注释将在代理之后丢失.


Dav*_*nni 7

使用

@Before("execution(* (@YourAnnotationAtClassLevel *).*(..))")
    public void beforeYourAnnotation(JoinPoint proceedingJoinPoint) throws Throwable {
}
Run Code Online (Sandbox Code Playgroud)


小智 6

像这样标记你的方面方法应该就足够了:

@After("@annotation(com.marcot.CommitTransaction)")
    public void after() {
Run Code Online (Sandbox Code Playgroud)

看一看一步一步的指南。