как сканировать / проверять Java-классы в пакете на аннотации @ slf4j - PullRequest
0 голосов
/ 09 апреля 2019

Новичок в Groovy и Spring пытается помочь нашей команде разработчиков с некоторыми функциями ведения журналов в нашей среде.

Я создал аспект MethodLogging для регистрации времени выполнения метода для любых классов с аннотацией @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 {}

Буду признателен за любые идеи или ресурсы о том, как подойти к этим усилиям.

1 Ответ

0 голосов
/ 10 апреля 2019

В принципе перехват @Slf4j будет таким же, как и для вашей собственной пользовательской аннотации , если (и только если) @Slf4j все еще будет присутствовать в байт-коде во время выполнения. Но на самом деле это не так. У него SOURCE срок хранения, как вы можете видеть в исходном коде аннотации .

Справочная информация: аннотация @Slf4j используется компилятором Groovy для динамического создания статического регистратора во время компиляции, чтобы сохранить вас в качестве стандартного пользовательского кода в ваших классах 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 только потому, что она не существует во время выполнения. Вам нужно будет найти другой способ достижения того, чего вы хотите. Одним из таких подходов может быть обработка аннотаций, поскольку она выполняется перед компиляцией.

...