如何在包中为@slf4j注释扫描/检查java类

问题描述 投票:0回答:1

groovy和Spring的新手试图帮助我们的Dev团队在我们的框架中使用一些日志记录功能。

我创建了一个MethodLogging Aspect来记录任何具有@Loggable注释的类的方法执行时间。

但是,作为第二阶段,我需要确定给定包中的类是否使用@slf4j注释并执行slf4j日志记录功能而不是@Loggable。

这是方面代码

import groovy.util.logging.Slf4j
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.annotation.Configuration

@Aspect
@Slf4j
public class LoggingAspect {
  // This is a Logging Aspect for the Loggable annotation that calculates
  // method runtimes for all methods under classes annotated with @Loggable

  @Around('execution (* *(..)) && @within(com.zions.common.services.logging.Loggable)')
  public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
    long start = System.currentTimeMillis();
    Object proceed = joinPoint.proceed();
    long executionTime = System.currentTimeMillis() - start;
    log.info("${joinPoint.getSignature()} executed in ${executionTime}ms");
    return proceed;
  }
}

这是@Loggable注释代码

package com.zions.common.services.logging

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

// Logging annotation to be used at class level

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

任何有关如何处理这项工作的想法或资源都将受到赞赏。

slf4j spring-aop
1个回答
0
投票

原则上拦截@Slf4j将与您自己的自定义注释相同,如果(并且仅当)@Slf4j在运行时期间仍然存在于字节代码中。但事实上并非如此。它有SOURCE保留,你可以在annotation source code看到。

背景:Groovy编译器使用@Slf4j注释,以便在编译期间动态创建静态记录器,以便将您保存为Groovy类中的用户样板代码。如果你反编译这个类......

package de.scrum_master.stackoverflow

import groovy.util.logging.Slf4j

@Slf4j
class FooBarZot {
  void test() {
    log.info("test")
  }
}

......你会看到这样的事情:

package de.scrum_master.stackoverflow;

import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;
import org.codehaus.groovy.runtime.callsite.CallSite;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class FooBarZot implements GroovyObject {
  private static final transient Logger log;

  public FooBarZot() {
    CallSite[] var1 = $getCallSiteArray();
    super();
    MetaClass var2 = this.$getStaticMetaClass();
    this.metaClass = var2;
  }

  public void test() {
    CallSite[] var1 = $getCallSiteArray();
    var1[0].call(log, "test");
  }

  static {
    Object var0 = $getCallSiteArray()[1].call(LoggerFactory.class, "de.scrum_master.stackoverflow.FooBarZot");
    log = (Logger)ScriptBytecodeAdapter.castToType(var0, Logger.class);
  }
}

因此,AspectJ不会帮助您拦截@Slf4j注释,因为它在运行时不存在。你需要找到另一种方法来实现你想要的。一种这样的方法可能是注释处理,因为它是在编译之前完成的。

© www.soinside.com 2019 - 2024. All rights reserved.