普通的MVC架构,Controller层是api的入口,现在想对每一个api的入参和返回值打印日志,用aspect 来实现很是方便。
本文侧重实践,概念层面就不在陈述了。
第一步:自定义一个打印日志的注解
/** * 自定义打印日志的注解 * */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface ServiceLog { }
这里对@Retention 和 @Target做一下说明。
@Retention属于元注解(元注解的作用就是负责注解其他注解,有@Retention/@Target/@Documented/@Inherited),
@Retention用于定于注解的生命周期,即在什么时期时期生效,有如下三个值:
1、RetentionPolicy.SOURCE:存在源码级,编译时就会被忽略
2、RetentionPolicy.CLASS:存在于编译期,即class中会有
3、RetentionPolicy.RUNTIME:在jvm运用时存在,能被读取到和使用
@Target是注解用在什么地方,是某个包、还是类、方法、构造器等等
ElemenetType.METHOD:方法
ElemenetType.PACKAGE :包
ElemenetType.PARAMETER :参数
等等
第二步:新增一个切面类,里面提供切入点方法和调用切点方法时机的方法
@Aspect @Component public class WebLogAscept { /** * 以自定义 @WebLog 注解为切点 */ // @Pointcut("@annotation(com.tm.backend.newapproval.aspect.WebLog)") // 扫描有WebLog注解的方法 @Pointcut("execution(* com.tm.backend.approval.endpoint.*.*(..))") // 扫描包下所有方法 public void webLog() { } /** * 切点之前 */ @Before("webLog()") public void doBefore(JoinPoint joinPoint) throws Throwable { // 开始打印请求日志 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); System.out.println("方法名:"+signature.getName()+". 入参:"+joinPoint.getArgs()); } /** * 环绕 */ @Around("webLog()") public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { Object result = proceedingJoinPoint.proceed(); System.out.println("返回值:"+result); return result; } }
总结:重点是自定义注解并且添加了切点后,这些切点在方法的什么地方用,并且获取相应的属性
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端