仅在某些方法中记录 sql 语句的执行时间

Logging execution time of sql statements inside certain methods only

我需要记录 SQL 语句的执行时间,但我只需要对某些流程执行此操作,例如假设我有一个包含多个 sql 语句的方法,我只需要仅记录以下语句在以下方法上的执行时间。

我正在执行以下操作以记录所有 sql 语句的执行时间,但我认为这是一种不好的做法,因为它可能会影响应用程序性能。

@Around("execution(* org.springframework.jdbc.core.JdbcTemplate..*(String, ..)) "
        + " || execution(* org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate..*(String, ..))")
public Object profile(ProceedingJoinPoint pjp) throws Throwable {
    final long start = System.currentTimeMillis();
    final Object obj = pjp.proceed();
    final long time = System.currentTimeMillis() - start;
    final String statement = pjp.getArgs()[0].toString();
    SqlTiming sqlTiming;
    synchronized(sqlTimings) {
        sqlTiming = sqlTimings.get(statement);
        if (sqlTiming == null) {
            sqlTiming = new SqlTiming(statement);
            sqlTimings.put(statement, sqlTiming);
        }
    }
    sqlTiming.recordTiming(time);
    LOGGER.perf().info("Sql: {}, {}, time: {} ms", pjp.getSignature().getName(), statement, time);

    return obj;
}

我的问题是如何仅在某些 methods/flows 中记录 sql 执行时间?

如果你想将切入点限制到某个执行流——在 AspectJ 术语中称为 "control flow"——你需要相应的切入点 cflow()cflowbelow()。但是如果你使用 Spring AOP,你不能像 manual 解释的那样使用它们。

因此,您需要切换到 AspectJ via LTW (load-time weaving),除非您想在运行时查看调用堆栈。但是当然,控制流切入点也在运行时进行评估,因为控制流是动态的。它仍然比手动操作快很多。

另一种方法是重构您的代码以通过特定的外观方法路由感兴趣的调用,而其他方法则转到其他地方。然后你可以很容易地写一个Spring AOP切入点。

正如他们所说,许多方法通向罗马 - 或通往耶路撒冷。