[英]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.