TraceAspect
구현으로 사용자 정의 @Traceable
주석이 있습니다. 메소드 호출 전후에 기록 할 메소드에 @Traceable
주석을 사용합니다. 방금 value
속성을 통해 사용하는 로그 수준을 @Traceable
(이전 버전은 항상 INFO
만 사용)으로 지정할 수있는 기능이 추가되었습니다. 내가 가지고있는 것은 효과가 있지만 더 효과적 일 수있는 방법이 있는지 궁금해하고 있습니다. 특히 어떤 종류의 aspect 컨텍스트가 있다면 을 @Traceable
에 주어진 방법으로 설정하는 것을 앱 시작시 한 번 수행 할 수 있습니다.내 aspect를보다 실행 가능하게 만들기 위해 joinpoint 주변의 AOP 전에 일회성 처리를 수행하는 방법이 있습니까?
@Traceable
주석 :
@Documented
@Retention(RUNTIME)
@Target(METHOD)
public @interface Traceable {
Level value() default Level.INFO;
}
현재 TraceAspect
IMPL : 내가 가진
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.event.Level;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class TraceAspect {
@Around("@annotation(com.collaterate.logging.Traceable)")
public Object traceAround(ProceedingJoinPoint joinPoint) throws Throwable {
Traceable traceable = ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotation(Traceable.class);
Logger classLog = LoggerFactory.getLogger(joinPoint.getSignature().getDeclaringType());
LoggingHelper loggingHelper = getLoggingHelper(traceable, classLog);
String methodName = joinPoint.getSignature().getName();
loggingHelper.log("{}() - started", methodName);
Object returnVal = joinPoint.proceed();
loggingHelper.log("{}() - ended", methodName);
return returnVal;
}
private LoggingHelper getLoggingHelper(Traceable traceable, Logger classLog) {
if (Level.INFO == traceable.value() || null == traceable.value()) {
// try to avoid the switch below... most of the time it will be INFO
return (format, args) -> classLog.info(format, args);
} else {
switch (traceable.value()) {
case ERROR :
return (format, args) -> classLog.error(format, args);
case WARN :
return (format, args) -> classLog.warn(format, args);
case DEBUG :
return (format, args) -> classLog.debug(format, args);
case TRACE :
return (format, args) -> classLog.trace(format, args);
default :
return (format, args) -> classLog.info(format, args);
}
}
}
@FunctionalInterface
interface LoggingHelper {
void log(String format, Object... args);
}
}
유일한 다른 아이디어 (각 로그 레벨 일) 후 TraceAspect
이를 IMPL 할 여러 주석을 만드는 것입니다 @Around
각 주석에 대한 핸들러이며 런타임에 반사/전환을 피할 수 있습니다. 여기서 싫어하는 점은 이미 여러 프로젝트에서 생산 코드 전체에 기존 @Traceable
주석을 사용하고 있다는 것입니다. 1 주석을 유지하고 속성을 통해 로그 수준을 지정할 수 있습니다.
이론적으로 프록시가 만들어 질 때 응용 프로그램 시작시 모든 정보가 있기 때문에 이론적으로 할 수 있어야합니다. 각 주석이 달린 메소드에는 일종의 컨텍스트가 있어야합니다.
'LogRegistry'를 사용합니까? 'Map' 대신에 자신의 bean으로 사용하는 것이 요점은 무엇입니까? – JeffNelson
필자의 경우, 다른 Spring 구성 요소가 레지스트리에 액세스했다. 엄지 규칙으로, 나는 일반적으로 전역 캐시/레지스트리를 별도의 Spring 관리 빈에 보관하여 여러 Spring 관리 빈이이를 액세스 할 수있게한다. Spring 구성 요소는 기본적으로 싱글 톤이므로 맵을 사용할 수도 있습니다. –