【问题标题】:Create AspectJ for annotation with Target=ElementType.TYPE (Class annotation)使用 Target=ElementType.TYPE(类注释)为注释创建 AspectJ
【发布时间】:2019-11-19 12:06:29
【问题描述】:

我想对带有自定义注释的注释类的所有方法执行简单的日志记录。我创建了下一个注释:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface FooAnnotation {}

它用于随机类:

@FooAnnotation
public class Bar{
  ...
}

当然我的开始类有@EnableAspectJAutoProxy 注解

@EnableAspectJAutoProxy
@SpringBootApplication
public class FooApplication {
  public static void main(String[] args) {
    SpringApplication.run(FooApplication.class, args);
  }
}

在相关的 AspectJ 中,我需要定义一个 @Pointcut 来对所有使用 @FooAnnotation注释的类的所有方法执行 @After >

我尝试了下一个 AspectJ,但它不起作用

@Slf4j
@Aspect
@Component
public class FooAspectJ{

  @Pointcut("within(x.y.z.FooNotify)")
  private void annotatedWithin() {}

  @Pointcut("@within(x.y.z.FooNotify)")
  private void annotatedAtWithin() {}

  @Pointcut("@annotation(x.y.z.FooNotify)")
  private void annotatedAtAnnotation() {}


  @After("annotatedWithin() || annotatedAtWithin() || annotatedAtAnnotation()")
  private void afterAnnotation(JoinPoint joinPoint){
    log.info("Executed annotated {}", joinPoint.getSignature().getName());
  }

}

我看到了类似的帖子,比如 @AspectJ pointcut for all methods of a class with specific annotationaspectj pointcut with annotation parameters,结果相同。

【问题讨论】:

    标签: java spring aop aspectj aspect


    【解决方案1】:

    应该是这样的

    @Pointcut("within(@x.y.z.FooNotify *)")
    

    示例:

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Repository;
    
    @FooNotify
    @Repository
    public class Bar {
      private static final Logger logger = LoggerFactory.getLogger(Bar.class);
    
      public String returnSomeString() {
        logger.info("returnSomeString ...");
        int i = returnMeAnInt();
        logger.info("returnMeAnInt returned {}", i);
        return "Hello";
      }
    
      public void doSomething() {
        logger.info("doSomething ...");
      }
    
      private int returnMeAnInt() {
        logger.info("returnMeAnInt ...");
        return 4;
      }
    }
    

    方面:

    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    
    @Component
    @Aspect
    public class BarAspect {
      private static final Logger logger = LoggerFactory.getLogger(BarAspect.class);
    
      @Pointcut("within(@FooNotify *)")
      public void fooNotifyPointcut() {}
    
      @After("fooNotifyPointcut()")
      public void afterAnnotation(JoinPoint jp) {
        logger.info("afterAnnotation joinpoint: {}", jp.getStaticPart().getSignature());
      }
    }
    

    注释:

    import static java.lang.annotation.ElementType.TYPE;
    import static java.lang.annotation.RetentionPolicy.RUNTIME;
    
    import java.lang.annotation.Retention;
    import java.lang.annotation.Target;
    
    @Retention(RUNTIME)
    @Target(TYPE)
    public @interface FooNotify {}
    

    致电:

     bar.returnSomeString();
        bar.doSomething();
    

    日志:

    Bar:13- returnSomeString ...

    Bar:24- returnMeAnInt ...

    Bar:15- returnMeAnInt 返回 4

    BarAspect:21- afterAnnotation 连接点:字符串 com.tierpoint.api.vcloud.Bar.returnSomeString()

    Bar:20- doSomething ...

    BarAspect:21- afterAnnotation 连接点: void com.tierpoint.api.vcloud.Bar.doSomething()

    对于私有方法,你必须使用完整的aspectj。

    【讨论】:

    • 它不起作用。我的班级在班级上用@FooNotify注释,当内部方法执行时不记录
    • 你的@FooNotify public class Bar{..}是弹簧组件吗?
    • 正确。这是一个@Repository
    • 它对我来说似乎工作正常..我会发布完整的例子
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-28
    • 1970-01-01
    • 2015-02-14
    • 2015-08-15
    • 2011-09-29
    • 1970-01-01
    • 2018-05-18
    相关资源
    最近更新 更多