在Spring AOP或AspectJ中拦截带注释的类和方法

时间:2019-06-05 06:46:14

标签: java spring-boot annotations aspectj spring-aop

所以我有一个自定义注释

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Intercepted {}

我想用来将方面编织成方法(AspectJ,@annotation(Intercepted))。

这个想法是,当我直接注释方法@Intercepted时,我就将方面编织了起来-该部分起作用了;或者,如果我注释了类,则应该将方面编织到其所有(公共)方法中- -那部分没有。

此外,如果我对类进行注释,则该方面仅应被编织一次,方法级注释将覆盖类级。

本质上,我希望“如果存在类级注释,则添加类级注释,但前提是还没有方法级注释。”

我该怎么做?

1 个答案:

答案 0 :(得分:0)

这是一个AspectJ示例。切入点语法在Spring AOP中是相同的。

帮助程序类:

sys.path
package de.scrum_master.app;

import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Intercepted {}
package de.scrum_master.app;

@Intercepted
public class AnnotatedClass {
  public void doSomething() {}
  public void doSomethingElse() {}
}
package de.scrum_master.app;

public class AnnotatedMethod {
  @Intercepted
  public void doSomething() {}
  public void doSomethingElse() {}
}

驱动程序应用程序(Java SE,没有Spring):

package de.scrum_master.app;

@Intercepted
public class AnnotatedMixed {
  @Intercepted
  public void doSomething() {}
  public void doSomethingElse() {}
}

方面:

请注意,Spring AOP中不需要package de.scrum_master.app; public class Application { public static void main(String[] args) { // Should be logged new AnnotatedClass().doSomething(); // Should be logged new AnnotatedClass().doSomethingElse(); // Should be logged new AnnotatedMethod().doSomething(); // Should NOT be logged new AnnotatedMethod().doSomethingElse(); // Should be logged, but only once new AnnotatedMixed().doSomething(); // Should be logged new AnnotatedMixed().doSomethingElse(); } } 部分,因为那里仅支持方法执行连接点。切入点可能只是execution(* *(..)) &&在那里。在AspectJ中,我必须更加精确,因为否则将记录其他联接点类型。

annotatedMethod() || annotatedClass()

控制台日志:

package de.scrum_master.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class AnnotationInterceptor {
  @Pointcut("@annotation(de.scrum_master.app.Intercepted)")
  public void annotatedMethod() {}

  @Pointcut("@within(de.scrum_master.app.Intercepted)")
  public void annotatedClass() {}

  @Before("execution(* *(..)) && (annotatedMethod() || annotatedClass())")
  public void log(JoinPoint thisJoinPoint) {
    System.out.println(thisJoinPoint);
  }
}