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

所以我有一个自定义注释


@Target({ElementType.METHOD, ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

@Inherited

@Documented

public @interface Intercepted {}

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


这个想法是,当我@Intercepted直接注释方法时,我将方面编织进去——那部分工作——或者如果我注释类,应该将方面编织到它的所有(公共)方法中——那部分不起作用。


此外,如果我注释一个类及其方法之一,则方面应该只编织一次,方法级别的注释覆盖类级别的注释。


本质上,我想要一个“如果有类级注释,则添加类级注释,但前提是还没有方法级注释”。


我怎么做?


GCT1015
浏览 112回答 1
1回答

白猪掌柜的

这是一个 AspectJ 示例。切入点语法在 Spring AOP 中是相同的。帮助类:package de.scrum_master.app;import java.lang.annotation.*;@Target({ElementType.METHOD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Inherited@Documentedpublic @interface Intercepted {}package de.scrum_master.app;@Interceptedpublic 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;@Interceptedpublic 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();  }}方面:请注意,该execution(* *(..)) &&部分在 Spring AOP 中不是必需的,因为那里仅支持方法执行连接点。切入点可能就在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;@Aspectpublic 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())
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java