# auto-annotation **Repository Path**: lindaifeng/auto-annotation ## Basic Information - **Project Name**: auto-annotation - **Description**: 🔥🔥🔥自定义注解集🔥🔥🔥开箱即用,通过注解实现对业务功能的增强,以极少的代码为项目赋能。功能实现有:【数据脱敏】【数据加解密】【接口限流】【日志收集】【参数校验】【防重复提交】【动态数据源】等等 - **Primary Language**: Java - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 6 - **Forks**: 0 - **Created**: 2023-06-13 - **Last Updated**: 2023-10-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README

logo

Auto-Annotation

一个注解实现对业务功能增强的注解集


## 项目简介 ​ 项目源码开源地址:[点这里](https://gitee.com/lindaifeng/auto-annotation) ​ 对业务开发过程中经常遇见的一些通用场景进行注解封装,形成一系列比较通用的注解集,来满足日常开发需要。注解集随业务拓展不断更新中,欢迎您的补充... ```java _ _ _ _ /\ | | /\ | | | | (_) / \ _ _| |_ ___ / \ _ __ _ __ ___ | |_ __ _| |_ _ ___ _ __ / /\ \| | | | __/ _ \ / /\ \ | '_ \| '_ \ / _ \| __/ _` | __| |/ _ \| '_ \ / ____ \ |_| | || (_) | / ____ \| | | | | | | (_) | || (_| | |_| | (_) | | | | /_/ \_\__,_|\__\___/ /_/ \_\_| |_|_| |_|\___/ \__\__,_|\__|_|\___/|_| |_| :: Project Version 1.0.0 :: auto-annotation:druid :: Running SpringBoot 2.6.5 :: ``` ## 项目引用 ​ 该项目已上传至`Maven`中央仓库,使用者可直接引用 ```xml io.github.lindaifeng auto-annotation 1.0.0 ``` ## 技术实现 #### 环境配置 ​ **运行环境**:`JDK1.8` ​ **开发工具:** `Idea`、`Maven` ​ **默认已启动中间件:**`Mysql8.0`、`Redis`、 ## 主要功能点展示 - 数据脱敏篇 `@SensitiveFiled` - 参数校验篇 `@MockValidator` - 防重复提交篇 `@RepeatSubmit` - 接口限流篇 `@RateLimit` - 强制登录篇 `@LoginRequired` - 日志记录篇 `@OperateLog` - 动态数据源篇 `@DynamicDb` - 数据加密篇 `@EncryptionFields` - ......... ### 数据脱敏篇 ​ 在日常业务开发中,我们会接触到各种各样的数据,这些数据可能包含用户敏感信息。如果这些敏感信息在传输和存储过程中被泄露,将会给用户带来不必要的麻烦和安全隐患。因此,数据脱敏技术的应用变得越来越重要。 ```java @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @JacksonAnnotationsInside @JsonSerialize(using = SensitiveFiledSerialize.class) public @interface SensitiveFiled { /** * 脱敏实现类 */ Class using(); /** * 脱敏前缀位数(自定义脱敏使用) */ int prefixHideLen() default 0; /** * 脱敏后缀位数(自定义脱敏使用) */ int suffixHideLen() default 0; /** * 脱敏符号(自定义脱敏使用) */ String symbol() default "*"; } ``` ### 参数校验篇 ​ API开发中经常会遇到一些对请求数据进行验证的情况,常规操作是不是在代码中进行if判断是否参数为空?这样显得很不优雅,这时候如果使用注解就有两个好处,一是验证逻辑和业务逻辑分离,代码清晰,二是验证逻辑可以轻松复用,只需要在要验证的地方加上注解就可。 ```java @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Constraint(validatedBy = MockValidatorImpl.class) public @interface MockValidator { /** * 校验响应信息 */ String message() default "xxx校验不通过"; /** * 校验分组 */ Class[] groups() default {}; /** * 自定义校验负载信息 */ Class[] payload() default {}; } ``` ### 防重复提交篇 ​ 在实际的开发项目中,一个对外暴露的接口往往会面临很多次请求,表单重复提交在日常 Web 应用中是最常见且带来麻烦最多的一个问题。 ​ 有很多的应用场景都会遇到表单重复提交问题,比如由于用户误操作,多次点击表单提交按钮;由于网速等原因造成页面卡顿,用户重复刷新提交页面,甚至会有黑客或恶意用户使用工具重复恶意提交表单来对网站进行攻击,这就造成请求发送多次,引发数据混乱,数据重复等问题,所以说防止表单重复提交在 Web 应用中的重要性是极高的。 ```java @Inherited @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RepeatSubmit { /** * 间隔时间(ms),小于此时间视为重复提交 */ int interval() default 5000; /** * 提示消息 */ String message() default "不允许重复提交,请稍后再试"; } ``` ### 接口限流篇 ​ 在访问高峰期为保证应用服务稳定运行,需要对高并发场景下接口进行接口限流处理,通对接口流量的访问限制能够在一定程度上防止接口被恶意调用的情况出现。 ```java @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RateLimit { /** * 限流key */ String key() default "rate_limit_key:"; /** * 限流时间,单位秒 */ int time() default 60; /** * 限流次数 */ int count() default 100; /** * 限流类型 */ RateLimitTypeEnum limitType() default RateLimitTypeEnum.GLOBAL; } ``` ### 强制登录篇 ​ 最近在一些业务场景中遇到这样的需求,有些接口需要登录后才能访问。我思考了一下,自定义注解的使用 注解+拦截器 实现登录校验,项目中在进入方法之前判断用户是否登录、登录了则继续执行方法,未登录则返回异常信息,或许是一个很不错的方法,当然类似黑名单的方式也可以,适合自己的最好。 ```java @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface LoginRequired { } ``` ### 日志记录篇 ​ 平时开发中,我们经常需要通过日志或者数据库来记录系统中一些重要的操作,如删除、修改和新增等。但每次在这些方法里手动打印日志或者记录到数据库太过繁琐,并且在代码中看到好多日志打印语句一点都不优雅。 ​ 通过自定义注解统一收集日志的方式来实现,则不需要在代码中考虑日志打印的问题,只需要在接口上打一个注解即可。 ```java @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented @Repeatable(OperateLogs.class) public @interface OperateLog { /** * 业务id */ String bid(); /** * 日志标签 */ String tag(); /** * 操作类型 */ OperateTypeEnum operateType(); /** * 日志消息 */ String message() default ""; /** * 操作人员 */ String operatorId() default ""; /** * 是否记录结果值 */ boolean recordResult() default false; /** * 结果值 */ String result() default ""; /** * 是否在方法执行后记录(默认方法执行前记录) */ boolean after() default false; } ``` ### 动态数据源篇 ​ 通常一个系统只需要连接一个数据库就可以了。但是在企业应用的开发中往往会和其他子系统交互,特别是对于一些数据实时性要求比较高的数据,我们就需要做实时连接查询,而不是做同步。这个时候就需要用到多数据源。 ​ 举个例子,在主从数据库的业务场景中,一个库用来读,一个库用来写,那么在进行数据库读写操作时就需要进行数据库的切换。 ```java @Target({ ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface DynamicDb { /** * 切换数据库源 */ DbType value() default DbType.PRIMARY_DB; } ``` ### 数据加密篇 ​ 前段时间在做密码测评时,遇到一个这样的业务场景,业务系统中的数据需要进行加密存储,在数据传输过程中进行加密传输。这就麻烦了,这数据可不光要加密,肯定也要解密呀,这再加上个传输加解密以及存储加解密,想想都麻烦,于是便想有什么办法能够写一套通用的代码来处理这种业务场景呢。 ​ 力求便捷,最先想到的便是自定义注解了,那么我能不能通过定义一个注解来标识哪些接口需要加解密传输,哪些字段需要加解密存储呢。于是数据加密篇便油然而生。 ```java @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface EncryptionFields { /** * 是否将接收到的参数解密存储 */ boolean decryptStorage() default false; /** * 是否将接收到的参数加密存储 */ boolean encryptStorage() default false; /** * 是否将查询到的结果解密返回 */ boolean decryptReturn() default false; /** * 是否将查询到的结果加密返回 */ boolean encryptReturn() default false; } ``` ## 总结 ​ 本项目为个人在闲暇之余的初创项目,代码结构总体比较简单易懂,内含详细的注释,非常适合新手以及无该业务场景经验者学习。 ​ 如果在使用过程中发现bug,或者你有一个很不错的自定义注解想法,欢迎给我提issues,我将会采用你的意见一起来丰富这个项目。 ​ 如果本项目对你有些帮助,欢迎给我一个🌟🌟🌟**star**🌟🌟🌟,让更多人知道它的存在,这对我很重要 。