簡體   English   中英

在Spring AOP或AspectJ中攔截帶注釋的類和方法

[英]Intercept annotated classes and methods in Spring AOP or AspectJ

所以我有一個自定義注釋

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

我想用來將方面編織到方法中(AspectJ, @annotation(Intercepted) )。

這個想法是當我直接對方法@Intercepted注釋時,我將方面編織起來–該部分起作用了;或者,如果我對類進行了注釋,則該方面應被編織到其所有(公共)方法中—該部分不被編織。

此外,如果我注釋一個類它的方法之一,該環節都要只得到穿插在一次,方法級別的注解覆蓋類級別的一個。

本質上,我希望“如果存在類級注釋,但僅當還沒有方法級注釋時,添加類級注釋”。

我怎么做?

這是一個AspectJ示例。 切入點語法在Spring AOP中是相同的。

助手類:

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() {}
}
package de.scrum_master.app;

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

驅動程序應用程序(Java SE,沒有Spring):

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();
  }
}

方面:

請注意,在Spring AOP中,無需execution(* *(..)) &&部分,因為那里僅支持方法執行連接點。 切入點可以只是annotatedMethod() || annotatedClass() annotatedMethod() || annotatedClass()在那里。 在AspectJ中,我必須更加精確,因為否則將記錄其他聯接點類型。

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);
  }
}

控制台日志:

execution(void de.scrum_master.app.AnnotatedClass.doSomething())
execution(void de.scrum_master.app.AnnotatedClass.doSomethingElse())
execution(void de.scrum_master.app.AnnotatedMethod.doSomething())
execution(void de.scrum_master.app.AnnotatedMixed.doSomething())
execution(void de.scrum_master.app.AnnotatedMixed.doSomethingElse())

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM