SpringAOP+自定义注解简单使用

news2024/11/26 2:40:06

一、SpringAOP简述


SpringAOP可以帮助我们在不修改源代码的前提下实现功能增强,其底层实现原理基于Java动态代理或者CGLIB。

在这里插入图片描述

之前我们使用 execution表达式指定被AOP增强的方法:(execution关键字用于描述哪些方法需要切面逻辑)

在这里插入图片描述

但是这样使用非常不灵活,因为并不是Service中所有的方法都需要被增强。

其实我们可以参考Spring声明式事务注解@Transactional,在项目中利用自定义注解实现了大量共性需求。


SpringAOP+自定义注解的应用场景:

  • 收集上报指定关键方法的入参、执行时间、返回结果等关键信息,用作后期调优处理;
  • 关键方法在幂等性前置校验(基于本地消息表);
  • 类似于Spring-Retryt模块,提供关键方法多次调用重试机制;
  • 提供关键方法自定义的快速熔断、服务降级等职责;
  • 关键方法的共性入参校验、权限校验;
  • 关键方法在执行后的扩展行为,例如记录日志、启动其他任务等;

二、SpringAOP+自定义注解使用


1、创建springboot工程,在pom.xml中引入aspectjweaver依赖

<!-- AOP切面编程框架 -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <!--<version>1.9.4</version>-->
</dependency>

2、编写自定义注解(使用@interface关键字定义注解)

package cn.baidou.dianping.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义方法注解
 */
// @Target(ElementType.METHOD) 用来约束这个自定义注解只能用在方法上
@Target(ElementType.METHOD)
// @Retention 用来控制注解的生命周期,RUNTIME表示这个注解一直存活 (作用在源码阶段,字节码文件阶段,运行阶段)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodExporter {

}

3、编写切面类

package cn.baidou.dianping.aop;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

/**
 * 获取目标入参、执行时间、执行过程、返回结果等细节并打印到日志上
 *
 * @author 白豆五
 * @version 2023/06/15
 * @since JDK8
 */
@Aspect //设置当前类为切面类
@Component //配置成Spring管理的bean
@Slf4j
public class MethodExporterAspect {
    
    /*
        @Around:环绕通知,最强大的通知类型,可以控制方法入参、执行、返回结果等各方面细节
        "@annotation(xxx.MethodExporter)":表示任何添加@MethodExporter注解的目标方法都将在执行方法前先执行该切面方法
     */
    @Around("@annotation(cn.baidou.dianping.annotation.MethodExporter)")
    public Object methodExporter(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();//开始时间
        Object proceed = joinPoint.proceed();      // 执行目标方法,获取方法返回值
        long endTime = System.currentTimeMillis(); //结束时间

        ObjectMapper mapper = new ObjectMapper();

        // 将入参JSON序列化
        String jsonParam = mapper.writeValueAsString(joinPoint.getArgs());//joinPoint.getArgs()获取目标方法的参数

        // 将返回结果JSON序列化
        String jsonResult = null;
        if (jsonResult != null) {
            jsonResult = mapper.writeValueAsString(proceed);//mapper.writeValueAsString()可用于将任何Java值序列化为字符串
        } else {
            jsonResult = "null";
        }

        // 模拟上报过程
        log.debug("正在上报服务器调用过程:\ntarget:{}.{}()\nexecution:{}ms,\nparameter:{}\nresult:{}",
                joinPoint.getTarget().getClass().getSimpleName(),
                joinPoint.getSignature().getName(),
                (endTime - startTime),
                jsonParam,
                jsonResult);

        return proceed;
    }
}

4、编写测试代码

package cn.baidou.dianping.controller;

import cn.baidou.dianping.annotation.MethodExporter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * @author 白豆五
 * @version 2023/06/15
 * @since JDK8
 */
@RestController
@RequestMapping("/test")
public class TestController {

    @MethodExporter
    @GetMapping("/list")
    public Map test() {
        Map resultMap = new LinkedHashMap();
        resultMap.put("code", "200");
        resultMap.put("message", "ok");

        try {
            TimeUnit.SECONDS.sleep(new Random().nextInt(10));
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return resultMap;
    }
}

5、重启项目,测试接口

在这里插入图片描述

控制台输出:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/651629.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络层:路由选择协议

1.网络层&#xff1a;路由选择协议 笔记来源&#xff1a; 湖科大教书匠&#xff1a;路由选择协议概述 湖科大教书匠&#xff1a;路由信息协议RIP的基本工作原理 湖科大教书匠&#xff1a;开放最短路径优先OSPF的基本工作原理 湖科大教书匠&#xff1a;边界网关协议&#xff08…

力扣题库刷题笔记7--N

1、题目如下&#xff1a; 2、个人Python代码实现&#xff1a; 看到此题的第一反应就是&#xff0c;生成一个类似二维数组的多个字符串&#xff0c;然后用个标志位控制N字符中字符的方向&#xff0c;例如flag True&#xff0c;在每次循环时候以flag flag * -1来控制。 由于示例…

嵌套虚拟机-Win10下的-wmware中的Ubuntu1804-使用KVM-安装win和ubuntu虚拟机

一、物理机操作 参考博文-CSDN-林麦安 -关于“ VMware Workstation 16 此平台不支持虚拟化的Intel VT-x/EPT. 不使用虚拟化的Intel VT-x/EPT,是否继续&#xff1f;”的有关问题的总结解答 在windows物理机搜索&#xff1a;内核隔离 把开关置为关 但是我的物理机这个选项已经是…

学习系统编程No.24【深入学习信号】

引言&#xff1a; 北京时间&#xff1a;2023/6/13/19:07&#xff0c;伴随着期末考的来临&#xff0c;最近停课啦&#xff01;无论是线上课&#xff0c;还是学校的课&#xff0c;开心&#xff0c;那这不是咱持续更文的好时候嘛&#xff0c;但是今天在学习相关C知识时&#xff0…

华为防火墙之安全策略

1.安全策略初体验 安全策略在防火墙转发报文的过程中扮演着重要角色&#xff0c;只有安全策略允许通过&#xff0c;报文才能在安全区域之间流动&#xff0c;否则报文将被丢弃。 先来看一个简单的网络环境&#xff0c;如下图&#xff1a; 如果想在防火墙上允许PC访问Web服务器…

NOTA-(COOt-Bu)3-Bn-NCS:一款多功能四氮杂环螯合剂标记

文章关键词&#xff1a;双功能螯合剂&#xff0c;大环化合物&#xff0c;有机双功能DOTA&#xff0c;金属离子螯合剂&#xff0c;四氮杂环螯合剂标记 【产品描述】 NOTA及其衍生物是新型双功能整合剂之一。NOTA及其衍生物具有良好的配位和鳌合能力&#xff0c;可作为过渡金属离…

vmstat调优命令

目录 一、vmstat命令描述 二、vmstat的语法格式 三、压力测试工具stress 实验&#xff1a; 模拟I/O负载 查看是哪个进程I/O读写高:pidstat -d (-d参数查看各进程io情况&#xff09; 总结 一、vmstat命令描述 vmstat命令&#xff1a; 用来获得有关进程、虚存、页面交换…

ChatGPT写文章

ChatGPT写小文章 只是个人对写小XX的心得?从知乎,知网自己总结的,有问题,可以留个言我改一下 被CSDN制裁过 关键词:论文 文章目录 ChatGPT写小文章-1.写XX模仿实战(狗头)0.XX组成1.好XX前提:2.标题3.摘要4.关键词5.概述6.实验数据、公式或者设计7.结论&#xff0c;思考8.参…

vsce报错The Personal Access Token verification has failed.,vsce login登录时同报此错的解决办法

本篇文章主要讲解vscode插件开发提交插件版本时出现的token报错问题的解决办法。 日期:2023年6月15日 作者:任聪聪 报错现象 1.vsce login 用户id报错如下: 具体报错内容: The Personal Access Token verification has failed. Additional information: Error: {"…

7.vue3医疗在线问诊项目 - _极速问诊-支付功能实现 ==> 预支付信息渲染、支付流程解析、订单生成、支付完成

7.vue3医疗在线问诊项目 - _极速问诊-支付功能实现 > 预支付信息渲染、支付流程解析、订单生成、支付完成 问诊支付-路由和预支付信息渲染{#pay-html} 实现&#xff1a;问诊页面路由配置&#xff0c;获取问诊预支付信息并渲染。 需求&#xff1a; 配置预订单信息页面路由定…

[学习笔记] [机器学习] 12. [上] HMM 隐马尔可夫算法(马尔科夫链、HMM 三类问题、前后后向算法、维特比算法、鲍姆-韦尔奇算法、API 及实例)

学习目标&#xff1a; 了解什么是马尔科夫链知道什么是 HMM 模型知道前向后向算法评估观察序列概率知道维特比算法解码隐藏状态序列了解鲍姆-韦尔奇算法知道 HMM 模型 API 的使用 1. 马尔科夫链 学习目标&#xff1a; 知道什么是马尔科夫链 在机器学习算法中&#xff0c;马…

【MySQL入门】-- 数据库介绍

目录 1.为什么要使用数据库&#xff1f; 2.数据库相关概念 3.数据库与数据库管理系统的关系 4.常见数据库排名 5.常见数据库的简单介绍 6.MySQL介绍 7.MySQL版本的选择 8.关系型数据库和非关系型数据库 9.关系型数据库设计规则以及规范 10.表的关系&#xff08;一对…

【Proteus仿真】51单片机+ADC0808模数转换数码管显示

【Proteus仿真】51单片机+ADC0808模数转换数码管显示 📺Proteus仿真演示: 📗ADC0808主要数据参数简介 8路输入通道,8位A/D转换器,即分辨率为8位:0 - 255。转换时间为100μs(时钟为640KHz时),130μs(时钟为500KHz时)。模拟输入电压范围0~+5V,不需零点和满刻度校准。…

谷粒商城第一天-项目概述、架构、Linux环境搭建

目录 一、学习的内容 一、常见的商城模式 二、谷粒商城项目的微服务架构 三、谷粒商城项目的微服务划分 四、谷粒商城项目的亮点 五、微服务的基本的概念 二、完成的进度 三、学到的东西 四、总结 6月9日正式下决心开始学习谷粒商城项目&#xff0c;之前早就听说谷粒商…

Powerjob部署安装

安装思路: 1、本地环境和具体生产环境都要安装部署jdk-------------------参考jdk安装 2、本地部署maven-------------------参考maven安装 3、本地部署powerjob 4、生成jar包,上传生产环境启动 部署: 1、下载上传Powerjob包,本次选取4.0.1版本 https://github.com/Powe…

arx程序与cgal冲突的地方,记录一下

arx本身是个dll&#xff0c;而且运行库是 /md&#xff0c;多线程&#xff0c;无论debug还是release都是/md&#xff0c;而不是/mtd cgal编译出来的库&#xff0c;release版本是Mt&#xff0c;debug版本是MTd 感觉debug版本是MTd对arx没用&#xff0c;不知道这种看法对不对&…

stable diffusion webui 安装部署(linux系统)

文中部署stable diffusion webui所使用的机器是腾讯云服务器linux系统&#xff0c;centos7 一 环境准备 在这里使用anaconda安装&#xff0c;优势就是可以方便地安装和管理软件包&#xff0c;同一系统上可以同时使用不同版本的 Python 和第三方软件包。如果你需要安装多个系统…

图像目标检测 - CenterNet: Objects as Points (arXiv 2019)

CenterNet: Objects as Points - 目标作为点&#xff08;arXiv 2019&#xff09; 摘要1. 引言2. 相关工作3. 准备工作4. 目标作为点4.1 3D 检测4.2 人体姿态估计 5. 实施细节6. 实验6.1 目标检测6.1.1 附加实验 6.2 3D 检测6.3 姿态估计 7. 结论References附录A&#xff1a;模型…

华为防火墙之攻击防范

1.DoS攻击简介 攻击和防御技术发展史 DoS是Denial of Service的简称&#xff0c;即拒绝服务。造成DoS的攻击行为被称为DoS攻击&#xff0c;其目的是使计算机或网络无法正常提供服务。 2.单包攻击及防御 最常见的DoS攻击就是单包攻击&#xff0c;一般都是以个人为单位的攻击者…

回归预测 | MATLAB实现SSA-CNN-BiGRU麻雀算法优化卷积双向门控循环单元多输入单输出回归预测

回归预测 | MATLAB实现SSA-CNN-BiGRU麻雀算法优化卷积双向门控循环单元多输入单输出回归预测 预测效果 基本介绍 MATLAB实现SSA-CNN-BiGRU麻雀算法优化卷积双向门控循环单元多输入单输出回归预测&#xff0c;运行环境Matlab2020b及以上。优化正则化率、学习率、隐藏层单元数。…