最简单的手动方式(手动包裹)
import java.util.logging.Logger;
public class TimerExample {
private static final Logger logger = Logger.getLogger(TimerExample.class.getName());
public static void main(String[] args) {
exampleFunction();
}
public static void exampleFunction() {
long start = System.nanoTime(); // 记录开始时间
try {
// 模拟业务逻辑
Thread.sleep(200);
System.out.println("Function is running...");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
long end = System.nanoTime();
logger.info("exampleFunction耗时: " + (end - start)/1_000_000.0 + " ms");
}
}
}
缺点:每个函数都要手动加计时,维护成本高。
使用 动态代理(适合接口函数)
如果你的函数都是接口方法,可以通过 动态代理 来拦截调用,自动统计运行时间:
import java.lang.reflect.*;
import java.util.logging.Logger;
public class TimingProxy {
private static final Logger logger = Logger.getLogger(TimingProxy.class.getName());
@SuppressWarnings("unchecked")
public static <T> T create(T target, Class<T> interfaceClass) {
return (T) Proxy.newProxyInstance(
interfaceClass.getClassLoader(),
new Class[]{interfaceClass},
(proxy, method, args) -> {
long start = System.nanoTime();
try {
return method.invoke(target, args);
} finally {
long end = System.nanoTime();
logger.info(method.getName() + "耗时: " + (end - start)/1_000_000.0 + " ms");
}
});
}
public static void main(String[] args) {
MyService service = new MyServiceImpl();
MyService proxy = TimingProxy.create(service, MyService.class);
proxy.doTask();
proxy.doOtherTask();
}
interface MyService {
void doTask();
void doOtherTask();
}
static class MyServiceImpl implements MyService {
public void doTask() {
try { Thread.sleep(150); } catch (InterruptedException ignored) {}
System.out.println("doTask done");
}
public void doOtherTask() {
try { Thread.sleep(250); } catch (InterruptedException ignored) {}
System.out.println("doOtherTask done");
}
}
}
优点:不修改原函数,自动统计接口方法耗时。
使用 AOP(Spring) 自动统计所有方法
如果你的项目是 Spring Boot/Java Spring,可以用 AOP 注解拦截函数,日志自动输出运行时间:
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import java.util.logging.Logger;
@Aspect
@Component
public class TimerAspect {
private static final Logger logger = Logger.getLogger(TimerAspect.class.getName());
// 拦截所有Service类下的方法
@Around("execution(* com.example.service..*(..))")
public Object measureExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.nanoTime();
Object result = joinPoint.proceed(); // 执行原方法
long end = System.nanoTime();
logger.info(joinPoint.getSignature() + "耗时: " + (end - start)/1_000_000.0 + " ms");
return result;
}
}
优点:几乎不改业务代码,自动统计所有目标包的方法运行时间。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70050070/viewspace-3117386/ ,如需转载,请注明出处,否则将追究法律责任。