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

AOP在业务中的简单使用

背景

业务组有一些给开发用的后门接口,为了做到调用溯源,业务组最近需要记录所有接口的访问记录,暂时只需要记录接口的响应结果,如果调用失败,则记录异常信息。由于后门接口较多以及只是业务组内部轻度使用,因此使用了切面的方式实现。

方案

@EnableAspectJAutoProxy
@Aspect
@Component
@Slf4j
public class ResponseLogAspect {@Resourceprivate CommonConstants commonConstants;@Pointcut("@annotation(*.log.ResponseLog)")public void logPointcut() {}/*** 执行成功打印*/@AfterReturning(pointcut = "logPointcut()", returning = "result")public void log(JoinPoint joinPoint, Object result) {try {// 降级开关if (!commonConstants.getBoolean("interface.response.log.switch", true)) {return;}ResponseLog annotation = findAnnotation(joinPoint, ResponseLog.class);String metric = metric(annotation.value(), joinPoint);log.info("interface success: {}, result: {}", metric, result);} catch (Exception e) {log.error("log error", e);QMonitor.recordOne("interface_response_log_fail");}}/*** 执行失败打印*/@AfterThrowing(pointcut = "logPointcut()", throwing = "error")public void logError(JoinPoint joinPoint, Throwable error) {try {// 降级开关if (!commonConstants.getBoolean("interface.response.log.switch", true)) {return;}ResponseLog annotation = findAnnotation(joinPoint, ResponseLog.class);String metric = metric(annotation.value(), joinPoint);log.error("interface fail: {}, error: {}", metric, error.getMessage());} catch (Exception e) {log.error("log error", e);QMonitor.recordOne("interface_response_log_fail");}}/*** 监控指标* @param specificName 具体指标名* @param point 切点* @return 指标名称*/private String metric(String specificName, JoinPoint point) {if (StringUtils.isBlank(specificName)) {String clz = point.getTarget().getClass().getSimpleName();String mtd = point.getSignature().getName();return clz + "_" + mtd;} else {return specificName;}}/*** 注解查询* @param point 切点* @param annotationType 注解类型* @return 注解信息*/private <A extends Annotation> A findAnnotation(JoinPoint point, Class<A> annotationType) {MethodSignature signature = (MethodSignature) point.getSignature();return AnnotationUtils.findAnnotation(signature.getMethod(), annotationType);}
}

接下来只需要在后门接口上增加对应的注解即可:

    @RequestMapping(value = "save", method = RequestMethod.POST)@ResponseBody@ResponseLog("/voucher/save")public APIResponse<Boolean> save(HttpServletRequest request, @RequestBody VoucherCommit voucherCommit) {// 代金券保存接口}

加餐

  1. @Target({ElementType.METHOD}):指定该注解可以应用于方法。如果不加这个注解,则表示默认该注解可以应用到类与方法上,但是加上后就表示这个注解只能作用于方法,否则会报错。
  2. springboot项目由于存在spring-boot-autoconfigure依赖,会默认开启aop代理,所以注解@EnableAspectJAutoProxy可以不用加,但是由于可以在配置文件中修改默认开启的逻辑,所以建议加上避免失效。
  3. @Pointcut注解中的参数:@within和@annotation。@annotation注解用于匹配那些具有指定注解的方法,@within注解用于匹配那些具有指定注解的类中的所有方法,即使这些方法本身没有显式地标注注解。
    // 切点:匹配带有@OnlyIntranetAccess注解的类@Pointcut("@within(org.openmmlab.platform.common.annotation.OnlyIntranetAccess)")public void onlyIntranetAccessOnClass() {}// 切点:匹配带有@OnlyIntranetAccess注解的方法@Pointcut("@annotation(org.openmmlab.platform.common.annotation.OnlyIntranetAccess)")public void onlyIntranetAccessOnMethed() {}

http://www.lryc.cn/news/392892.html

相关文章:

  • C# 用户权限界面的测试内容
  • PyCharm
  • 【嵌入式开发 Linux 常用命令系列 1.5 -- grep 过滤特定类型文件】
  • 学习笔记——动态路由——OSPF(邻接/邻居)
  • k8s 答疑
  • [终端安全]-2 移动终端之硬件安全(SE)
  • 数据库与SQL
  • AIGC | 在机器学习工作站安装NVIDIA CUDA® 并行计算平台和编程模型
  • 【电商纯干货分享】干货速看!电商数据集数据API接口数据分析大全!
  • 随手记录: Ubuntu NVIDIA显卡驱动安装后 屏幕亮度无法调节 无法连接外显示器等问题
  • Java:数组
  • 【代码随想录——图论——岛屿问题】
  • 异步调用 - 初识
  • Java 家庭物联网
  • 机器学习——随机森林
  • Java - JDK17语法新增特性(如果想知道Java - JDK17语法新增常见的特性的知识点,那么只看这一篇就足够了!)
  • Linux-DNS
  • 使用gitlab的CI/CD实现logseq笔记自动发布为单页应用
  • 云联壹云 FinOps:赋能某车企公有云成本管理与精细化运营
  • C#静态类与非静态类
  • 亚信安全:《2024云安全技术发展白皮书》
  • GuLi商城-商品服务-API-品牌管理-云存储开通与使用
  • git 命令行初始化并上传项目
  • Spring框架Mvc(2)
  • Python学习笔记29:进阶篇(十八)常见标准库使用之质量控制中的数据清洗
  • 【LLM】一、利用ollama本地部署大模型
  • Java毕业设计 基于SSM vue新生报到系统小程序 微信小程序
  • 玩转云服务:Oracle Cloud甲骨文永久免费云服务器注册及配置指南
  • Zabbix——宏
  • Unity 简单载具路线 Waypoint 导航