java自定义注解 方法运行时间
使用场景
面向切面,记录service方法运行时间。
定义注解类 TimeMonitor
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TimeMonitor {
}
创建切面配置类 MonitorAspect
@Aspect:作用是把当前类标识为一个切面供容器读取
@Pointcut:Pointcut是植入Advice的触发条件。每个Pointcut的定义包括2部分,一是表达式,二是方法签名。方法签名必须是 public及void型。可以将Pointcut中的方法看作是一个被Advice引用的助记符,因为表达式不直观,因此我们可以通过方法签名的方式为 此表达式命名。因此Pointcut中的方法只需要方法签名,而不需要在方法体内编写实际代码。
@Around:环绕增强,相当于MethodInterceptor
@AfterReturning:后置增强,相当于AfterReturningAdvice,方法正常退出时执行
@Before:标识一个前置增强方法,相当于BeforeAdvice的功能,相似功能的还有
@AfterThrowing:异常抛出增强,相当于ThrowsAdvice
@After: final增强,不管是抛出异常或者正常退出都会执行
import java.util.Arrays;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class MonitorAspect {
private static final Logger logger = LoggerFactory.getLogger(MonitorAspect.class);
// 修正Timer注解的全局唯一限定符
@Pointcut("@annotation(com.kxb.microservice.inter.TimeMonitor)")
private void pointcut() {
}
@Around("pointcut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取目标Logger
// 获取目标类名称
String clazzName = joinPoint.getTarget().getClass().getName();
// 获取目标类方法名称
String methodName = joinPoint.getSignature().getName();
long start = System.currentTimeMillis();
logger.error("{}: {}: start...", clazzName, methodName);
String targetMethodParams = Arrays.toString(joinPoint.getArgs());
// 调用目标方法
Object result = joinPoint.proceed();
long time = System.currentTimeMillis() - start;
logger.error("{}: {}: {}: end... cost time: {} ms", clazzName, methodName, targetMethodParams, time);
return result;
}
}
在service类的方法上加上注解@TimeMonitor
执行此方法之后打印出运行时间
public class ConsumerService {
@TimeMonitor
public Map<String, Object> execute(String text) {
Map<String, Object> dealResult = null;
String uuid = PubFun.getUUID(); // 标记整条流程数据
try {
logger.info("分发器接收入口ActiveMq 接受队列信息text:{}...uuid:{}", text, uuid);
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> param = mapper.readValue(text, HashMap.class);
param.put(Constant.MSG_TEXT, text);
// 执行代码
} catch (Exception e) {
logger.error("异常:{}", e);
}
return dealResult;
}
}
运行日志如下:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)