Spring boot实现基于注解的aop面向切面编程

Spring boot实现基于注解的aop面向切面编程

背景

从最开始使用Spring,AOP和IOC的理念就深入我心。正好,我需要写一个基于注解的AOP,被这个注解修饰的参数和属性,就会被拿到参数并校验参数。

一,引入依赖

当前spring boot版本为2.7.18,我引入的aspectjweaver版本为1.9.5。

     <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.5</version></dependency>

二,写注解

这个注解用来修饰方法,相当于一个切点,加上这个注解,这个方法就被被aop执行。

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ParamInterceptor {boolean checkParam() default true;
}

在这里插入图片描述
这个注解是用来修饰参数和属性的。被修饰的参数和属性在aop中会通过反射取出数据并判断

@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface VerifyParam {int min() default -1;int max() default -1;boolean required() default false;VerifyRegexEnum regex() default VerifyRegexEnum.NO;
}

这个是用到的VerifyRegexEnum 枚举类

@AllArgsConstructor
@Getter
public enum VerifyRegexEnum {NO("", "不校验"),IP("^((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})$", "ip地址"),POSITIVE_INTEGER("^\\d+$", "正整数"),NUMBER_LETTER_UNDER_LINE("\\w+$", "数字字母下划线"),PHONE("^1[3-9]\\d{9}$", "手机号"),EMAIL("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$", "邮箱"),ID_CARD("^\\d{17}(\\d|x|X)$", "身份证"),PASSWORD("^[a-zA-Z0-9]{6,20}$", "密码"),MONEY("^\\d+(\\.\\d+)?$", "金额"),;private String regex;private String desc;public static boolean isMatch(String regex, String str) {return str.matches(regex);}}

三,编写切面aspect

该切面类就实现了,对参数和属性的校验。

@Aspect
@Component
@Slf4j
public class CdesAspect {@Before("@annotation(com.cdes.annotation.ParamInterceptor)")public void before(JoinPoint point) {Object[] args = point.getArgs();Method method = ((MethodSignature) point.getSignature()).getMethod();log.info("参数校验,方法名:{}",method.getName());ParamInterceptor paramInterceptor = method.getAnnotation(ParamInterceptor.class);if (paramInterceptor == null ) {return;}if(!paramInterceptor.checkParam()){return;}try{checkParam(method,args);}catch (Exception e){throw new BizException("400",e.getMessage());}}private void checkParam(Method method, Object[] args) throws IllegalAccessException {Parameter[] parameters = method.getParameters();for (int i = 0; i < parameters.length; i++) {Parameter parameter = parameters[i];Object paramValue = args[i];VerifyParam paramAnnotation = parameter.getAnnotation(VerifyParam.class);//取方法参数上的注解,如果有,则校验参数,如果没有,取该参数的属性,看是否有该注解if (paramAnnotation != null) {if(paramAnnotation.required() && paramValue == null){throw new BizException( "400",parameter.getName()+":参数不能为空");}if(paramAnnotation.max() != -1){if (paramValue.toString().length() > paramAnnotation.max()) {throw new BizException( "400",parameter.getName()+":参数长度不能超过"+paramAnnotation.max());}}if(paramAnnotation.min() != -1){if (paramValue.toString().length() < paramAnnotation.min()) {throw new BizException( "400",parameter.getName()+":参数长度不能小于"+paramAnnotation.min());}}if(paramAnnotation.regex() != null){if(!VerifyRegexEnum.isMatch(paramAnnotation.regex().getRegex(),paramValue.toString())){throw new BizException( "400",parameter.getName()+":参数不符合正则表达式");}}}else{//取属性上的注解,看是否需要校验Field[] fields = parameter.getClass().getDeclaredFields();if(fields == null || fields.length == 0){continue;}for (Field field : fields) {field.setAccessible(true);VerifyParam ann = field.getAnnotation(VerifyParam.class);if(ann == null){continue;}Object filedValue = field.get(paramValue);if(ann.required() && filedValue == null){throw new BizException( "400",field.getName()+":参数不能为空");}if(ann.max() != -1){if (filedValue.toString().length() > ann.max()) {throw new BizException( "400",field.getName()+":参数长度不能超过"+ann.max());}}if(ann.min() != -1){if (filedValue.toString().length() < ann.min()) {throw new BizException( "400",field.getName()+":参数长度不能小于"+ann.min());}}if(ann.regex() != null){if(!VerifyRegexEnum.isMatch(ann.regex().getRegex(),filedValue.toString())){throw new BizException( "400",field.getName()+":参数不符合正则表达式");}}}}}}
}

四,使用

controller中的login方法加上了ParamInterceptor注解,然后这个方法的入参LoginDTO中的属性加上了VerifyParam注解
在这里插入图片描述

@Data
@AllArgsConstructor
@NoArgsConstructor
public class LoginDTO {@VerifyParam(regex = VerifyRegexEnum.PHONE)private String phone;@VerifyParam(regex = VerifyRegexEnum.PASSWORD)private String password;@VerifyParam(required = true)private String verifyCode;@VerifyParam(required = true)private String codeId;
}

总结

经过测试,校验参数功能正常。可以看到,spring boot的aop功能使用起来还是相当简单的。

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

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

相关文章

寒武纪:“国产平替”道阻且长

英伟达的一季报反映了AI装备竞赛白热化&#xff0c;科技巨头们正疯狂加码投资。 不过&#xff0c;因为众所周知的原因,英伟达最先进的产品卖不到国内&#xff0c;虽然说一定程度上限制了咱们AI的发展&#xff0c;但也给国产AI芯片公司们提供了机会&#xff0c;其中就包括我们今…

K8S==ingress简单搭建和使用

基础环境 D:\DOCKER_REPO\K8S>kubectl version Client Version: v1.29.2 Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3 Server Version: v1.29.2 D:\DOCKER_REPO\K8S>kubectl get nodes NAME STATUS ROLES AGE VERSION docker-…

01_深度学习基础知识

1. 感知机 感知机通常情况下指单层的人工神经网络,其结构与 MP 模型类似(按照生物神经元的结构和工作原理造出来的一个抽象和简化了模型,也称为神经网络的一个处理单元) 假设由一个 n 维的单层感知机,则: x 1 x_1 x1​ 至 x n x_n xn​ 为 n 维输入向量的各个分量w 1 j…

【大学物理】Interference,diffraction,polarization:光学

nature of light definition speed of light reflection dispersion huygenss principle:惠更斯原理

OBD诊断协议

上周领导需要做个OBD相关的功能&#xff0c;我对OBD没有啥概念&#xff0c;于是周末就了解下这到底是个啥东西。了解过后发现很简单&#xff0c;其实就是个UDS协议的简化版&#xff0c;OBD是英文On-Board Diagnostics的缩写&#xff0c;中文翻译为“车载自动诊断系统”&#xf…

链表反转--理解链表指针的基本操作

链表反转--理解链表指针的基本操作 链表反转的方法--主要是理解链表指针链表心得类节点是对象和指针区别&#xff1a; 链表反转的方法–主要是理解链表指针 根据值创建新列表 用一个链表指针代替整个新链表 两个链表的赋值 递归求解反向链表 用一个链表代替前后链表数…

Qt应用程序发布

一、静态编译发布 1.0:以Release模式构建工程 1.1:查看当前构建生成路径,并将所生成的.exe单独拷贝出来 1.2:将可执行文件*.exe拷贝至任一目标文件夹:D:\Temporary\QQIF 2:查看安装Qt时发布工具windeployqt.exe所在的目录 windeployqt.exe在Qt开发套件的bin目录下。Qt的每…

构建高效稳定的短视频直播系统架构

随着短视频直播的迅猛发展&#xff0c;构建一个高效稳定的短视频直播系统架构成为了互联网企业的重要挑战。本文将探讨如何构建高效稳定的短视频直播系统架构&#xff0c;以提供优质的用户体验和满足日益增长的用户需求。 ### 1. 短视频直播系统的背景 短视频直播近年来蓬勃发…

Pycharm 添加内容根

解决问题&#xff1a;包未能被正常引入时

try…except…finally语句

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 完整的异常处理语句应该包含finally代码块&#xff0c;通常情况下&#xff0c;无论程序中有无异常产生&#xff0c;finally代码块中的代码都会被执行…

2024 年该如何利用 MidJourney 创作AI艺术(详细教程)

什么是 Midjourney Midjourney 是根据文本提示创建图像的生成式人工智能的优秀范例。与 Dall-E 和 Stable Diffusion 一样&#xff0c;它已成为最受欢迎的人工智能艺术创作工具之一。与竞争对手不同的是&#xff0c;Midjourney 是自筹资金和封闭源代码的&#xff0c;因此对它的…

【WRF理论第二期】模型目录介绍

WRF理论第二期&#xff1a;模型目录介绍 1 WRF主目录2 WPS主目录3 编译后的可执行文件4 运行目录参考 了解 WRF 模型的目录结构有助于有效地管理和操作模型&#xff0c;从而确保模拟和分析工作的顺利进行。以下分解介绍WRF主目录、WPS主目录等。 Github-wrf-model/WRF 1 WRF…

leetCode-hot100-二分查找专题

二分查找 简介原理分析易错点分析例题33.搜索旋转排序数组34.在排序数组中查找元素的第一个和最后一个位置35.搜索插入位置240.搜索二维矩阵 Ⅱ 简介 二分查找&#xff0c;是指在有序&#xff08;升序/降序&#xff09;数组查找符合条件的元素&#xff0c;或者确定某个区间左右…

找不到steam_api64.dll,无法继续执行的原因及解决方法

电脑已经成为我们生活中不可或缺的一部分。然而&#xff0c;在使用电脑的过程中&#xff0c;我们经常会遇到一些常见的问题&#xff0c;其中之一就是找不到某个特定的动态链接库文件&#xff0c;比如steamapi64.dll。这个问题可能会导致某些应用程序无法正常运行&#xff0c;给…

关于博图17安装体验过程—博图17安装失败原因(STEP7 许可证找不到)

目录 一、序言 二、正片 一、序言 该失败原因是在我使用Win11专业版安装博图17时出现的问题&#xff0c;也仅代表我的体验过程&#xff01;以下我将安装过程和解决问题的过程描述一下&#xff0c;希望可以帮助和我一样自己安装博图时能够解决出现的问题。 二、正片 如果阁下…

linux驱动学习(五)之字符设备

需要板子一起学习的可以这里购买&#xff08;含资料&#xff09;&#xff1a;点击跳转 一、 linux设备驱动分类 1、字符设备---char 应用程序与驱动程序在进行数据传输时&#xff0c;数据以"字节"为单位。 特点&#xff1a; [1] 按照顺序进行数据传输 [2] 数据传…

vscode专区

1.展示多行的文件导航标签,而非只有1行 1.1打开设置 1.2搜索该设置"workbench.editor.wrap.tabs",并勾选 1.3效果对比

vue+vscode 快速搭建运行调试环境与发布

1.安装node.js Node.js — Run JavaScript Everywhere 默认不断next 2.更换镜像地址 运行-cmd 执行以下代码安装 npm config set registry https://registry.npmmirror.com 检查node.js和镜像是否是否成功 node -v npm -v npm config get registry 3.安装打包工具 …

吊车报警的工作原理和使用场景_鼎跃安全

在现代建筑施工过程中&#xff0c;经常使用大型机械设备&#xff0c;如挖掘机、吊车、打桩机等&#xff0c;这些设备在施工过程中发挥着越来越重要的作用&#xff1b;同时&#xff0c;这些设备的作业频繁进行作业&#xff0c;对于接触到高压电线的风险也随之增加。大型机械设备…

Leetcode学习

回文数 反转一半数字 第一个想法是将数字转换为字符串&#xff0c;并检查字符串是否为回文。 但是&#xff0c;这需要额外的非常量空间来创建问题描述中所不允许的字符串。 第二个想法是将数字本身反转&#xff0c;然后将反转的数字与原始数字比较&#xff0c;如果它们是相同…