spring的自定义注解

在 Spring 中,自定义注解可以帮助我们实现自定义的功能,比如切面逻辑、权限控制、数据校验等。自定义注解通常结合 Spring 的 AOP 或其他功能使用,以增强业务逻辑。下面是创建自定义注解的一般步骤,以及使用示例。


一、创建自定义注解

1.1 定义自定义注解

创建一个自定义注解需要使用 @interface 关键字,同时可以添加一些元注解来控制注解的行为:

  • @Target:指定注解可以应用的位置(类、方法、字段等)。
  • @Retention:指定注解的生命周期。
  • @Documented:将注解包含在 Javadoc 中。
  • @Inherited:允许子类继承父类的注解。
示例:定义一个自定义注解 @LogExecutionTime
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.METHOD) // 只能作用于方法
@Retention(RetentionPolicy.RUNTIME) // 在运行时可见
public @interface LogExecutionTime {
}

二、使用 AOP 处理自定义注解

可以通过 AOP 来处理带有 @LogExecutionTime 注解的方法,记录方法执行时间。

2.1 创建切面类

在切面类中,通过 @Around 注解拦截标注了 @LogExecutionTime 的方法,计算并打印执行时间。

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;@Aspect
@Component
public class LoggingAspect {@Around("@annotation(LogExecutionTime)")public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {long start = System.currentTimeMillis();// 执行目标方法Object proceed = joinPoint.proceed();long executionTime = System.currentTimeMillis() - start;System.out.println(joinPoint.getSignature() + " executed in " + executionTime + "ms");return proceed;}
}
2.2 在方法上使用注解

可以将 @LogExecutionTime 注解添加到任何方法上,Spring AOP 会自动拦截并记录执行时间。

import org.springframework.stereotype.Service;@Service
public class MyService {@LogExecutionTimepublic void serve() {// 模拟耗时操作try {Thread.sleep(200);} catch (InterruptedException e) {Thread.currentThread().interrupt();}System.out.println("Service executed");}
}

三、实现基于自定义注解的权限控制示例

下面示例通过自定义注解实现简单的权限控制,模拟权限验证功能。

3.1 定义权限控制注解

创建 @RoleRequired 注解,指定需要的角色。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RoleRequired {String value(); // 指定需要的角色
}
3.2 创建权限控制的切面类

在切面类中,通过拦截 @RoleRequired 注解的方法,实现权限验证的逻辑。

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.JoinPoint;
import org.springframework.stereotype.Component;@Aspect
@Component
public class RoleAspect {// 假设当前用户角色(在实际中,这个信息可能来自上下文或会话)private static final String currentUserRole = "USER";@Before("@annotation(roleRequired)")public void checkRole(JoinPoint joinPoint, RoleRequired roleRequired) {String requiredRole = roleRequired.value();// 检查当前用户的角色if (!currentUserRole.equals(requiredRole)) {throw new SecurityException("Access Denied: insufficient permissions");}System.out.println("Access Granted: " + joinPoint.getSignature());}
}
3.3 使用权限控制注解

@RoleRequired 注解添加到需要权限控制的方法上。

import org.springframework.stereotype.Service;@Service
public class AdminService {@RoleRequired("ADMIN")public void performAdminTask() {System.out.println("Admin task performed");}
}

在运行时,如果当前用户的角色不匹配 @RoleRequired 指定的角色,将抛出异常 Access Denied: insufficient permissions


四、使用自定义注解进行参数校验

自定义注解还可以用于参数校验,结合 Spring 的 @Validated 注解,利用 AOP 实现校验逻辑。

4.1 定义注解 @NotEmpty

创建一个 @NotEmpty 注解,用于校验字段不为空。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NotEmpty {String message() default "Field cannot be empty";
}
4.2 创建校验器

编写 AOP 切面类,检测带有 @NotEmpty 注解的字段是否为空。

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.JoinPoint;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;@Aspect
@Component
public class ValidationAspect {@Before("execution(* com.example..*.*(..))")public void validateNotEmptyFields(JoinPoint joinPoint) throws IllegalAccessException {Object[] args = joinPoint.getArgs();for (Object arg : args) {if (arg != null) {Field[] fields = arg.getClass().getDeclaredFields();for (Field field : fields) {if (field.isAnnotationPresent(NotEmpty.class)) {field.setAccessible(true);Object value = field.get(arg);if (value == null || (value instanceof String && ((String) value).trim().isEmpty())) {NotEmpty notEmpty = field.getAnnotation(NotEmpty.class);throw new IllegalArgumentException(notEmpty.message());}}}}}}
}
4.3 使用校验注解

在实体类中使用 @NotEmpty 注解标记需要校验的字段。

public class User {@NotEmpty(message = "Username must not be empty")private String username;@NotEmpty(message = "Password must not be empty")private String password;// Constructors, getters, and setters
}
4.4 在服务中进行校验

调用带有 @NotEmpty 注解的对象时,如果字段为空,会触发校验异常。

import org.springframework.stereotype.Service;@Service
public class UserService {public void registerUser(User user) {System.out.println("User registered: " + user.getUsername());}
}

总结

自定义注解结合 AOP 可以极大地简化代码,并添加业务逻辑。以上示例展示了几种常见的自定义注解应用场景:

  • 方法执行时间记录@LogExecutionTime
  • 权限控制@RoleRequired
  • 字段校验@NotEmpty

自定义注解使代码更加简洁、可读、可复用。根据业务需求,可以灵活实现多种注解应用。

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

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

相关文章

python代码中通过pymobiledevice3访问iOS沙盒目录获取app日志

【背景】 在进行业务操作过程中,即在app上的一些操作,在日志中会有对应的节点,例如,下面是查看设备实时视频过程对应的一些关键节点: 1、TxDeviceAwakeLogicHelper:wakeStart deviceId CxD2BA11000xxxx …

网络编程_day6

目录 【0】复习 并发服务器实现思路梳理 多进程 多线程 IO多路复用select 【1】setsockopt:设置套接字属性 socket属性 设置地址重用 【2】超时检测 必要性 超时检测的设置方法 1. 通过函数自带的参数设置 2. 通过设置套接字属性进行设置 3. alarm函数与sigaction函…

GPT-Sovits-1-数据处理

1.1 切割音频 将音频切割为多个10s内的片段 1.2 降噪 这一步用的是modelscope的pipeline 如果要去除背景音,可以用傅立叶转为为频谱,去除低频部分后再转回来 1.3 提取音频特征 这里用到了 funasr 库 这一步目的是输出音频样本的《文本标签文件》&am…

Linux——常见指令及其权限理解(正在更新中)

1.指令 1.1 快速了解指令 pwd 首次登录,默认所处的路径 whoami 当前所用的用户的名称 ls 显示当前路径下,文件名称 mkdir 在当前目录下,创建一个文件夹/目录 cd 进入一个目录 touch 新建一个文…

Kafka 物理存储机制

优质博文:IT-BLOG-CN 一个商业化消息队列的性能好坏,其文件存储机制设计是衡量一个消息队列服务技术水平和最关键指标之一。下面将从Kafka文件存储机制和物理结构角度,分析Kafka是如何实现高效文件存储,及实际应用效果。Kafka的基…

采用STM32CubeMX和HAL库的定时器应用实例

目录 STM32的通用定时器配置流程 定时器应用的硬件设计 定时器应用的软件设计 1. 通过STM32CubeMX新建工程 通过STM32CubeMX新建工程的步骤如下: 2. 通过Keil MDK实现工程 通过Keil MDK实现工程的步骤如下: STM32的通用定时器配置流程 通用定时器…

【优选算法篇】前缀之序,后缀之章:于数列深处邂逅算法的光与影

文章目录 C 前缀和详解:基础题解与思维分析前言第一章:前缀和基础应用1.1 一维前缀和模板题解法(前缀和)图解分析C代码实现易错点提示代码解读题目解析总结 1.2 二维前缀和模板题解法(二维前缀和)图解分析C…

Topaz Video AI for Mac 视频无损放大软件安装教程【保姆级,操作简单轻松上手】

Mac分享吧 文章目录 Topaz Video AI for Mac 视频无损放大软件 安装完成,软件打开效果一、Topaz Video AI 视频无损放大软件 Mac电脑版——v5.3.5⚠️注意事项:1️⃣:下载软件2️⃣:安装软件,将安装包从左侧拖入右侧文…

CNAS软件测试的好处有哪些?上海软件测试中心推荐

在进行软件测试或其他项目检测需要选择软件测试中心时,我们常常会把该公司有无资质认证考虑进去。那么CNAS认可作为检测机构或实验室的一项重要资质认证,我们可能会产生疑问:CNAS认可什么意思?CNAS软件测试又有什么好处呢? 1、CNAS认可是什…

【51 Pandas+Pyecharts | 深圳市共享单车数据分析可视化】

文章目录 🏳️‍🌈 1. 导入模块🏳️‍🌈 2. Pandas数据处理2.1 读取数据2.2 查看数据信息2.3 处理起始时间、结束时间2.4 增加骑行时长区间列2.5 增加骑行里程区间列 🏳️‍🌈 3. Pyecharts数据可视化3.1 各…

AMBA之AXI 总线

AMBA概述 AMBA(Advanced Microcontroller Bus Architecture)是ARM公司开发的一种高级微控制器总线架构,用于连接处理器、存储器和外设的通信。AMBA总线架构定义了一组协议和接口,用于实现高性能、低功耗、可扩展的系统设计。 AM…

Amcor 如何借助 Liquid UI 实现SAP PM可靠性

背景介绍 安姆科是塑料行业的全球领军企业,该企业认识到 SAP 工厂维护(SAP PM)对于确保高效的维护管理的重要性。 在诸如制造业等高度依赖机械设备的行业中,SAP PM是一种通过数据驱动决策来最大限度减少停机时间、降低间接成本、…

【C语言】预处理(预编译)详解(下)(C语言最终篇)

文章目录 一、#和##1.#运算符2.##运算符 二、预处理指令#undef三、条件编译1.单分支条件编译2.多分支条件编译3.判断符号是否被定义4.判断符号是否没有被定义 四、头文件的包含1.库头文件的包含2.本地头文件的包含3.嵌套包含头文件的解决方法使用条件编译指令使用预处理指令#pr…

宠物空气净化器哪个牌子好?有没有噪音低的宠物空气净化器推荐?

如今随着社会竞争越来越激烈,不少人开始焦虑内耗,但为了能更好的生活,养宠物便成为不少人的排忧解乏的方法。 我也不例外,作为一名996社畜,天刚亮就出门,天黑很久才回家,所以选择养猫来陪我度过…

C++设计模式创建型模式———生成器模式

文章目录 一、引言二、生成器/建造者模式三、总结 一、引言 上一篇文章我们介绍了工厂模式,工厂模式的主要特点是生成对象。当对象较简单时,可以使用简单工厂模式或工厂模式;而当对象相对复杂时,则可以选择使用抽象工厂模式。 工…

创作三周年:在忙碌中寻找灵感与快乐

目录 机缘 收获 技能的提升 粉丝的积累 正向的反馈 同行的伙伴 日常 运动 旅行 生活 憧憬 结语 机缘 不知不觉已经成为创作者3年了,这一路走来,有过高峰和低谷,但始终让我坚持的,是最初那份简单的初心:我…

C#从零开始学习(用户界面)(unity Lab4)

这是书本中第四个unity Lab 在这次实验中,将学习如何搭建一个开始界面 分数系统 点击球,会增加分数 public void ClickOnBall(){Score;}在OneBallBehaviour类添加下列方法 void OnMouseDown(){GameController controller Camera.main.GetComponent<GameController>();…

分布式搜索引擎elasticsearch操作文档操作介绍

1.DSL查询文档 elasticsearch的查询依然是基于JSON风格的DSL来实现的。 1.1.DSL查询分类 Elasticsearch提供了基于JSON的DSL&#xff08;Domain Specific Language&#xff09;来定义查询。常见的查询类型包括&#xff1a; 查询所有&#xff1a;查询出所有数据&#xff0c;…

软件系统安全保证措施,质量保证措施方案(Word原件套用)

系统安全保证措施是构建稳固防御体系的核心&#xff0c;旨在全方位保障信息系统的安全性。以下是对这七项措施的简要概述&#xff1a; 一、身份鉴别&#xff1a;采用多种认证方式&#xff0c;如密码、生物识别等&#xff0c;确保用户身份的准确无误&#xff0c;防止非法入侵。 …

玩转Docker | 使用Docker部署捕鱼网页小游戏

玩转Docker | 使用Docker部署捕鱼网页小游戏 一、项目介绍项目简介项目预览 二、系统要求环境要求环境检查Docker版本检查检查操作系统版本 三、部署捕鱼网页小游戏下载镜像创建容器检查容器状态下载项目内容查看服务监听端口安全设置 四、访问捕鱼网页小游戏五、总结 一、项目…