Spring Boot如何自定义注解?
1.什么是注解
注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
元注解
有一些注解可以修饰其他注解,这些注解就称为元注解(meta annotation)。Java标准库已经定义了一些元注解,我们只需要使用元注解,通常不需要自己去编写元注解。
@Target
最常用的元注解是@Target。使用@Target可以定义Annotation能够被应用于源码的哪些位置:
- 类或接口:
ElementType.TYPE; - 字段:
ElementType.FIELD; - 方法:
ElementType.METHOD; - 构造方法:
ElementType.CONSTRUCTOR; - 方法参数:
ElementType.PARAMETER。
例如,定义注解@Report可用在方法上,我们必须添加一个@Target(ElementType.METHOD):
@Target(ElementType.METHOD)
public @interface Report {int type() default 0;String level() default "info";String value() default "";
}
定义注解@Report可用在方法或字段上,可以把@Target注解参数变为数组{ ElementType.METHOD, ElementType.FIELD }:
@Target({ElementType.METHOD,ElementType.FIELD
})
public @interface Report {...
}
实际上@Target定义的value是ElementType[]数组,只有一个元素时,可以省略数组的写法。
@Retention
另一个重要的元注解@Retention定义了Annotation的生命周期:
- 仅编译期:
RetentionPolicy.SOURCE; - 仅class文件:
RetentionPolicy.CLASS; - 运行期:
RetentionPolicy.RUNTIME。
如果@Retention不存在,则该Annotation默认为CLASS。因为通常我们自定义的Annotation都是RUNTIME,所以,务必要加上@Retention(RetentionPolicy.RUNTIME)这个元注解:
@Retention(RetentionPolicy.RUNTIME)
public @interface Report {int type() default 0;String level() default "info";String value() default "";
}
@Repeatable
使用@Repeatable这个元注解可以定义Annotation是否可重复。这个注解应用不是特别广泛。
@Repeatable(Reports.class)
@Target(ElementType.TYPE)
public @interface Report {int type() default 0;String level() default "info";String value() default "";
}@Target(ElementType.TYPE)
public @interface Reports {Report[] value();
}
经过@Repeatable修饰后,在某个类型声明处,就可以添加多个@Report注解:
@Report(type=1, level="debug")
@Report(type=2, level="warning")
public class Hello {
}
@Inherited
使用@Inherited定义子类是否可继承父类定义的Annotation。@Inherited仅针对@Target(ElementType.TYPE)类型的annotation有效,并且仅针对class的继承,对interface的继承无效:
@Inherited
@Target(ElementType.TYPE)
public @interface Report {int type() default 0;String level() default "info";String value() default "";
}
在使用的时候,如果一个类用到了@Report:
@Report(type=1)
public class Person {
}
则它的子类默认也定义了该注解:
public class Student extends Person {
}
2.代码工程
实验目的
实现统计方法执行时间的注解
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springboot-demo</artifactId><groupId>com.et</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>annotations</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId></dependency><dependency><groupId>org.assertj</groupId><artifactId>assertj-core</artifactId></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId></dependency><!-- fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.21</version></dependency></dependencies>
</project>
controller
使用自定义注解@RequestTime
package com.et.annotation.controller;import com.et.annotation.RequestTime;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;
import java.util.Map;@RestController
public class HelloWorldController {@RequestMapping("/hello")@RequestTimepublic Map<String, Object> showHelloWorld(){Map<String, Object> map = new HashMap<>();map.put("msg", "HelloWorld");return map;}
}
custom annotation
自定义@RequestTime注解
package com.et.annotation;import java.lang.annotation.*;/*** computa the excute time for the method*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface RequestTime {}
具体的拦截逻辑类
package com.et.annotation;import com.et.annotation.util.AspectUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;import java.lang.reflect.Method;@Slf4j
@Aspect
@Component
public class RequestTimeAspect {@Pointcut(value = "@annotation(com.et.annotation.RequestTime)")public void pointcut() {}@Around("pointcut()")public Object handle(ProceedingJoinPoint point) throws Throwable {Method currentMethod = AspectUtil.getMethod(point);long starttime = System.currentTimeMillis();Object result = point.proceed();long endtime = System.currentTimeMillis();long requesttime =endtime-starttime;//if(requesttime>1000){log.info(AspectUtil.getClassName(point)+"."+currentMethod.getName()+"execute time:"+requesttime+" ms");//}return result;}
}
以上只是一些关键代码,所有代码请参见下面代码仓库
代码仓库
- https://github.com/Harries/springboot-demo(annotations)
3.测试
- 启动Spring Boot应用程序
- 访问http://127.0.0.1:8088/hello
- 控制台输出 日志
2024-08-10 19:30:43.670 INFO 3343 --- [nio-8088-exec-1] com.et.annotation.RequestTimeAspect : com_et_annotation_controller_HelloWorldController.showHelloWorldexecute time:41 ms
4.引用
- https://www.baeldung.com/java-custom-annotation
- Spring Boot如何自定义注解? | Harries Blog™
相关文章:
Spring Boot如何自定义注解?
1.什么是注解 注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元…...
gin框架传入的gin.context参数是池化的
1. gin.context参数不但是池化的,而且是指针 2. 但是gin.context又实现了context的接口。因此,可以当作context去使用 3. 这就会导致一个很严重的问题: 1. 池化导致了复用后的ctx将会将之前使用的ctx中的内容进行覆盖。 2. 实现了context接…...
AWS注册是否必须使用美元银行卡
亚马逊网络服务(AWS)作为全球领先的云计算平台,吸引了众多企业和个人用户。然而,不少人在注册AWS账户时会产生疑问:是否必须使用美元银行卡?实际上,这种说法并不准确。虽然AWS的主要结算货币是美元,但用户在注册和使用过程中有多种支付方式可供选择。我们结合九河云的分析来告…...
Spring IOC 注入的3种方式
Spring IOC 注入的3种方式 1. 构造器注入(Constructor Injection)2. Setter方法注入(Setter Injection)3. 字段注入(Field Injection) 💖The Begin💖点点关注,收藏不迷路…...
无人机影像基于机器学习的遥感反演及其结果可视化,定量遥感反演结果出图,相关性分析,指标筛选,特征选择
无人机影像或者卫星遥感反演分类模型的建立,反演模型的可视化制图出图,相关性分析,指标筛选,特征选择。代码太多,可企鹅联系: 指标的相关性分析。572 特征选择,贡献性最大的特征。412 LAI反演&…...
Eclipse插件之Java Dependency Viewer(显示类和包的关系图)
Java Dependency Viewer 插件的作用 Eclipse插件Java Dependency Viewer是一个为Java项目提供依赖关系可视化功能的工具。 在复杂的Java项目中,理解和分析类与类之间、包与包之间的依赖关系是非常有用的。Java Dependency Viewer插件通过生成依赖关系图,…...
H5小游戏出海,如何流量变现?
根据数据显示, 90%的轻度休闲游戏收入来自广告,即IAA(In-App Advertising)。使用这种形式进行变现的游戏类型大多以超休闲游戏为主,玩法简单、游戏内容轻度、风格简洁、游戏时间碎片化且即时娱乐性较高,收益…...
轻空间六大专利优势:引领气膜建筑新时代
在绿色建筑和科技创新的驱动下,轻空间不断突破传统建筑的限制,推出了一系列具有前瞻性和高性能的专利技术。通过这些技术,轻空间不仅为建筑行业注入了新动力,也为未来的气膜建筑设定了更高的标准。 低碳建材:“clearsk…...
LeetCode-day37-2940. 找到 Alice 和 Bob 可以相遇的建筑
LeetCode-day37-2940. 找到 Alice 和 Bob 可以相遇的建筑 题目描述示例示例1:示例2: 思路代码 题目描述 给你一个下标从 0 开始的正整数数组 heights ,其中 heights[i] 表示第 i 栋建筑的高度。 如果一个人在建筑 i ,且存在 i &…...
unity 判断平台
原文链接 Unity中判断平台的方法 Unity提供了一些方法来判断当前运行的平台,其中包括了判断是否为i0S平台。以下是几种常用的方法1.Application.platform Applicaion,platom 是Unity中的一个枚举类型,用于表示当前运行的平台。可以通过比较 Apication,p…...
PyCharm找不到Python了咋办
Python发生了重装的,且新的路径和原有路径不同,就会出现如下的错误: 解决办法: 点开PyCharm菜单的File/Setting 然后: 有上图的提示,说明需要将原来的venv进行清空。 如此操作之后,原来的红色…...
BRC-100 协议
BRC-100 协议 BRC-100 是一种基于序数理论的可扩展的去中心化计算协议。 BRC-100 协议会以下面的方式定义。未来所有的 BRC-100 协议栈都应该使用类似的规范来定义。 1. 摘要 BRC-100 协议是一种基于序数理论的可扩展的去中心化计算协议。 2. 抽象 BRC-100 协议本质上描述…...
茶余饭后(六)
年少成长的时候,多遇到一些所谓的“坏人”,“烂人”,其实是好的,因为这些人让你见识到了人性最丑陋的一面,他们让你磨炼了心性,在以后遇到难处理的人或事的时候,能够有一定的心理承受能力。遇见…...
秋招复习笔记——八股文部分:网络IP
终于来到了网络的最后一篇,继续加油! IP 知识全家桶 IP 基本认识 IP 在 TCP/IP 参考模型中处于第三层,也就是网络层。 网络层的主要作用是:实现主机与主机之间的通信,也叫点对点(end to end)…...
量化投资基础(四)之AR、MA、ARMA与ARIMA模型
点赞、关注,养成良好习惯 Life is short, U need Python 量化投资基础系列,不断更新中 1 引言 时间序列经典模型主要有: 自回归模型(Auto Regressive,AR)移动回归模型(Moving Average,MA&…...
LVS(Linux Virtual Server)详解
LVS(Linux Virtual Server)是一个用于负载均衡的开源软件项目,旨在通过集群技术实现高性能、高可用的服务器系统。它运行在Linux操作系统上,并且可以利用内核级的资源来提高性能和稳定性。 思维导图 LVS的工作原理 LVS主要基于Ne…...
uniapp版本更新除了plus.runtime.getProperty的解决办法
以下是展示图 带尺寸的图片: 首先把以下代码放到想要更新弹出的页面 //template部分<uni-popup ref"popup" background-color"#fff"><versionUp handleCloseVersion"closeVersion"></versionUp></uni-popup>//script…...
MySQL笔记-基础篇(二):多表查询
博客主页: 南来_北往 系列专栏:Spring Boot实战 前言 MySQL的多表查询是一项非常实用的数据库操作技术,它能够通过关联不同表中的数据来提供更加丰富和准确的信息。在实际应用中,数据通常不是孤立存在的,而是分布在多个…...
备战秋招60天算法挑战,Day15
题目链接: https://leetcode.cn/problems/minimum-window-substring/ 视频题解: https://www.bilibili.com/video/BV1sJ4m1g727/ LeetCode 76. 最小覆盖子串 题目描述 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s …...
【学习笔记】Matlab和python双语言的学习(整数规划和0-1规划)
文章目录 前言一、整数规划和0-1规划二、典型示例1.背包问题2.指派问题 三、代码实现----Matlab1.Matlab 的 intlinprog 函数2.Matlab 代码背包问题指派问题 四、代码实现----python背包问题指派问题 总结 前言 通过模型算法,熟练对Matlab和python的应用。 学习视频…...
遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
