当前位置: 首页 > news >正文

spring中的切面类实践

目标功能:自定义一个在方法执行前后做日志记录的切面方法,需要考虑到方法执行成功与失败的情况,并记录方法名与意义与参数。

自定义的切面类需要配套一个自定义注解执行

import java.lang.annotation.*;@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
@Documented
public @interface LogRec {String value() default ""; // 接口名称描述
}

切面类的类层面

@Aspect
@Component
public class LogRecordAspect {private static final Logger logger = LoggerFactory.getLogger(LogRecordAspect.class);@Autowiredprivate SystemService systemService;@Pointcut("@annotation(com.example.config.aspect.LogRec)")public void logRecMethods() { }...
}

类里面环绕目标方法的增强方法

    /*** 环绕通知并记录日志* @param joinPoint* @param logRec* @return* @throws Throwable*/@Around("logRecMethods() && @annotation(logRec)")public Object logAround(ProceedingJoinPoint joinPoint, LogRec logRec) throws Throwable {long startTime = System.currentTimeMillis();// 获取注解值String methodDesc = logRec.value();Object result = null;Object logRes = null;try {// 获取 requestHttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();// 执行原方法result = joinPoint.proceed();logRes = result;//logRes可以用来做额外处理,保留最终返回的result的完整性,避免误修改//正常日志记录...return result;} catch (Exception e) {//异常日志记录logger.error("接口调用异常:{}", e.getMessage(), e);throw e;} finally {//收尾代码...}}

起初考虑不全时,只想到before和after,这里也记录一下。特别提示:这俩和around不能共存。

    @Before("logRecMethods() && @annotation(logRec)")public void logBefore(JoinPoint joinPoint,LogRec logRec){String methodName = joinPoint.getSignature().getName();String methodParams = logRec.value();String interfaceName = joinPoint.getTarget().getClass().getName();logger.info("【"+interfaceName+"】"+methodName+"("+methodParams+")");Object[] args = joinPoint.getArgs();for (Object arg : args){if (arg instanceof HttpServletRequest){HttpServletRequest request = (HttpServletRequest) arg;systemService.writeReqLog(request,methodParams+":开始执行");}}}
    @After("logRecMethods() && @annotation(logRec)")public void logAfter(JoinPoint joinPoint,LogRec logRec){String methodName = joinPoint.getSignature().getName();String methodParams = logRec.value();;String interfaceName = joinPoint.getTarget().getClass().getName();logger.info("【"+interfaceName+"】"+methodName+"("+methodParams+")");Object[] args = joinPoint.getArgs();for (Object arg : args){if (arg instanceof HttpServletRequest){HttpServletRequest request = (HttpServletRequest) arg;systemService.writeReqLog(request,methodParams+":结束执行");}}}

除了环绕方法,还有出现异常时的处理方法

    /*** 异常通知:记录失败日志*/@AfterThrowing(pointcut = "logRecMethods()", throwing = "ex")public void logAfterThrowing(JoinPoint joinPoint, Throwable ex) {String methodName = joinPoint.getSignature().getName();String methodParams = ex.getMessage();String interfaceName = joinPoint.getTarget().getClass().getName();logger.info("【"+interfaceName+"】"+methodName+"("+methodParams+")");Object[] args = joinPoint.getArgs();for (Object arg : args){if (arg instanceof HttpServletRequest){HttpServletRequest request = (HttpServletRequest) arg;systemService.writeReqLog(request,"发生异常:"+ex.getMessage());}}}
http://www.lqws.cn/news/509995.html

相关文章:

  • WPF CommunityToolkit.Mvvm
  • 【技术难题】el-table的全局数据排序实现示例,不受分页影响,以及异步请求带来的页面渲染问题
  • 针对基于深度学习的侧信道分析(DLSCA)进行超参数的贝叶斯优化
  • VIVADO导出仿真数据到MATLAB中进行分析
  • python基础(字符串-复习)
  • 关于素数、唯一分解等内容的详细讲解(从属于GESP五级)
  • vscode + Jlink 一键调试stm32 单片机程序(windows系统版)
  • HarmonyOS Next的HiLog日志系统完全指南:从入门到精通
  • I2C设备树参数详解
  • 猿人学js逆向比赛第一届第十三题
  • 多线程的同步
  • docker部署oracle数据库
  • Leetcode+JAVA+回溯1
  • i.MX平台下 Linux + FreeRTOS 协同启动与通讯全解(含Yocto实战与核心机制分析)
  • ​CentOS 7 单用户模式重置 root 密码完整指南
  • 无人机神经网络模块运行与技术难点
  • Dify与代理商奇墨科技为企业定制AI应用开发专属方案,适配多样化业务需求
  • vue-25( Composition API 与现有的 Options API 组件集成)
  • 采用ArcGIS10.8.2 进行插值图绘制
  • DEYOLO 全面复现,将双增强跨模态目标检测网络 DEYOLO 融合到 YOLOFuse 框架
  • C++字符大小
  • P0/P1级重大故障根因分析:技术挑战与无指责复盘文化
  • Leaking GAN
  • 医学数据分析实战:冠心病发病因素可视化
  • git学习资源
  • 轨迹降噪API及算法
  • 应用层协议 HTTP
  • 洛谷P1092 [NOIP 2004 提高组] 虫食算
  • openai-agents实现out_guardrails
  • DataSophon 1.2.1集成Flink 1.20并增加JMX 监控