繁体   English   中英

有没有一种方法可以在围绕连接点的AOP之前进行一次性处理,以使我的方面更加高效?

[英]Is there a way to do one-time processing before an AOP around joinpoint to make my aspect more performant?

我有一个带有TraceAspect实现的自定义@Traceable批注。 我们在要在方法调用前后记录的方法上使用@Traceable批注。 我们刚刚添加了通过@Traceable value属性指定要使用的日志级别的@Traceable (旧版本始终仅使用INFO )。 我所拥有的有效,但是我想知道是否有一种方法可以使其表现更好。 具体来说,如果存在某种方面的上下文,则可以在应用启动时检查@Traceable为给定方法在@Traceable设置的value

@Traceable批注:

@Documented
@Retention(RUNTIME)
@Target(METHOD)
public @interface Traceable {

    Level value() default Level.INFO;
}

当前的TraceAspect

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是,我们已经在多个项目的整个生产代码中使用了现有的@Traceable批注。 我想保留1批注,并允许它通过属性指定日志级别。

从理论上讲,我想做的事情应该是可能的,因为创建代理时,所有信息都在应用程序启动时出现。 每个带注释的方法都必须具有某种上下文。

我已经对指标进行了类似的操作。 您可以使用class and method pair作为并使用LoggingHelper作为来维护日志注册表。

如果该类方法对在日志注册表中没有条目,请创建一个日志记录帮助程序并将其存储在注册表中。 第二次,您只需在注册表中查找它。

注册表是一个自定义的Spring bean,应该自动连接到您的方面。

这是修改后的TraceAspect的示例。

@Component
@Aspect
public class TraceAspect {

    private LogRegistry registry;

    @Autowired
    public TraceAspect(LogRegistry registry) {
        this.registry = registry;
    }

    @Around("@annotation(com.collaterate.logging.Traceable)")
    public Object traceAround(ProceedingJoinPoint joinPoint) throws Throwable {
        String loggerName = joinPoint.getSignature()
           .getDeclaringType().getCanonicalName() + "." 
              + joinPoint.getSignature().getName();

        LoggingHelper loggingHelper = registry.get(loggerName);
        if (loggingHelper == null) {
            Traceable traceable = ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotation(Traceable.class);
            Logger classLog = LoggerFactory.getLogger(joinPoint.getSignature().getDeclaringType());
            loggingHelper = getLoggingHelper(traceable, classLog);
            registry.put(loggerName, loggingHelper)
        }

        String methodName = joinPoint.getSignature().getName();
        loggingHelper.log("{}() - started", methodName);
        Object returnVal = joinPoint.proceed();
        loggingHelper.log("{}() - ended", methodName);

        return returnVal;
    }
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM