SpringBoot如何自定义注解

SpringBoot如何自定义注解

​ 在Java中,我们可以创建自定义注解,这是一种应用于类、方法、变量、参数和包等元素的元数据。自定义注解可以帮助我们更好地组织和处理代码。需要注意的是,自定义注解本身不会改变代码的行为。它们只是一种元数据,可以被其他代码读取和处理。要使注解有用,我们需要编写一些处理这些注解的代码,例如反射。

1.注解定义

  1. Annotation型定义为@interface, 所有的Annotation会自动继承java.lang.Annotation这一接口,并且不能再去继承别的类或是接口.
  2. 参数成员只能用public或默认(default)这两个访问权修饰
  3. 参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和String、Enum、Class、annotations等数据类型,以及这一些类型的数组.
  4. 要获取类方法和字段的注解信息,必须通过Java的反射技术来获取 Annotation对象,因为你除此之外没有别的获取注解对象的方法
  5. 注解也可以没有定义成员, 不过这样注解就没啥用了

2.如何自定义注解

对注解有了一个基本的认识:注解其实就是一种标记,可以在程序代码中的关键节点(类、方法、变量、参数、包)上打上这些标记,然后程序在编译时或运行时可以检测到这些标记从而执行一些特殊操作。因此可以得出自定义注解使用的基本流程:

第一步,定义注解——相当于定义标记;
第二步,配置注解——把标记打在需要用到的程序代码中;
第三步,解析注解——在编译期或运行时检测到标记,并进行特殊操作。

3.注解的分类

3.1 jdk的基本注解

① @Override
重写
②@Deprecated
已过时
③@SuppressWarnings(value = “unchecked”)
压制编辑器警告

3.2 JDK元注解

@Retention、@Target、@Inherited、@Documented这些注解是元注解,用于修饰我们自定义的注解。

 元注解用于修饰其他的注解
① @Retention:定义注解的保留策略@Retention(RetentionPolicy.SOURCE)             //注解仅存在于源码中,在class字节码文件中不包含@Retention(RetentionPolicy.CLASS)              //默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,@Retention(RetentionPolicy.RUNTIME)            //注解会在class字节码文件中存在,在运行时可以通过反射获取到② @Target:指定被修饰的Annotation可以放置的位置(被修饰的目标)@Target(ElementType.TYPE)                      //接口、类@Target(ElementType.FIELD)                     //属性@Target(ElementType.METHOD)                    //方法@Target(ElementType.PARAMETER)                 //方法参数@Target(ElementType.CONSTRUCTOR)               //构造函数@Target(ElementType.LOCAL_VARIABLE)            //局部变量@Target(ElementType.ANNOTATION_TYPE)           //注解@Target(ElementType.PACKAGE)                   //包 注:可以指定多个位置,例如:@Target({ElementType.METHOD, ElementType.TYPE}),也就是此注解可以在方法和类上面使用③ @Inherited:指定被修饰的Annotation将具有继承性 ④@Documented:指定被修饰的该Annotation可以被javadoc工具提取成文档.

4.通过反射解析自定义注解

  • 定义在类上的注解
package com.hh.test.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Author {String name() default "HH";String email() default "unknown";
}

使用@Author注解

package com.hh.test.annotation;@Author(name = "wk", email = "xxxxxx@qq.com")
public class Hello {public static void main(String[] args) {}@Log(value = "测试日志写入", type = "2")public void testLog() {}
}

通过反射获取注解的值

  Class<?> clazz = Hello.class;if (clazz.isAnnotationPresent(Author.class)) {Author author = clazz.getAnnotation(Author.class);System.out.println("Author: " + author.name() + ", Email: " + author.email());}
  • 定义在方法上面的注解
import java.lang.annotation.*;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface Log {String value() default "";String type() default "1";
}

使用@Log注解

 @Log(value = "测试日志写入", type = "2")public void testLog() {}

通过反射获取注解的值

   Log log = clazz.getMethod("testLog").getAnnotation(Log.class);System.out.printf("日志的内容:%s \n", log.value());System.out.printf("日志的类型:%s", log.type());

5.通过Springboot使用自定义注解

首先,我们创建一个Spring Boot项目,添加maven依赖spring-boot-starter-aopspring-boot-starter-aop 模块自身提供了针对 spring-aopaspectjrtaspectjweaver 的依赖,包含了我们实现自定义注解的所有功能。

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>

创建一个方法级别的注解

import java.lang.annotation.*;
/*** 定义一个方法级别的@SaveSystemLog注解,用于标注需要监控的方法:*/
@Target(ElementType.METHOD)
@Retention(value = RetentionPolicy.RUNTIME)
@Documented
public @interface SaveSystemLog {/*** 操作名称*/String value() default "";/*** 日志类别*/String type() default "1";
}

创建切面实现类SystemLogAspect

public class SystemLogAspect {@Pointcut("execution(* com.hh.test.controller.*.*(..)) && @annotation(com.hh.test.annotation.SaveSystemLog)")public void pointcut() {}@Around("pointcut()")public Object around(ProceedingJoinPoint point) {Object result = null;long beginTime = System.currentTimeMillis();try {// 执行方法result = point.proceed();} catch (Throwable e) {log.error(e.getMessage());}// 执行时长(毫秒)long time = System.currentTimeMillis() - beginTime;// 保存日志saveLog(point, time);return result;}private void saveLog(ProceedingJoinPoint joinPoint, long time) {MethodSignature signature = (MethodSignature) joinPoint.getSignature();Method method = signature.getMethod();SaveSystemLog logAnnotation = method.getAnnotation(SaveSystemLog.class);System.out.println("日志保存成功:"+logAnnotation.value());}
}

测试一下

public class Test {@RequestMapping("/log")@SaveSystemLog(value = "测试日志")public void saveLog(){System.out.println("123");}
}

6.总结

主要是重点关注下@Target@Retention这两个注解。

@Target注解,他的作用是将这个注解放在什么地方,比如类上、方法上、构造器上、变量上等,他的值是一个枚举类型的。

public enum ElementType {/** Class, interface (including annotation type), or enum declaration */TYPE,/** Field declaration (includes enum constants) */FIELD,/** Method declaration */METHOD,/** Formal parameter declaration */PARAMETER,/** Constructor declaration */CONSTRUCTOR,/** Local variable declaration */LOCAL_VARIABLE,/** Annotation type declaration */ANNOTATION_TYPE,/** Package declaration */PACKAGE,/*** Type parameter declaration** @since 1.8*/TYPE_PARAMETER,/*** Use of a type** @since 1.8*/TYPE_USE
}

@Retention 注解,它的作用是为了说明这个注解的生命周期,也可以说是注解的保留位置。

在注解中有三个生命周期,即

  1. RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;
  2. RetentionPolicy.CLASS:注解在编译时被保留(默认的保留策略),但Java VM在运行时不需要它。这意味着这个注解信息不会被加载到JVM中。
  3. RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;

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

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

相关文章

使用Ant Design Pro开发时的一个快速开发接口请求的技巧

使用Ant Design Pro开发时的一个快速开发接口的技巧 当我们的后端在写好接口以后&#xff0c;我们通过swagger knife4j可以生成一个接口文档&#xff0c;后端启动以后&#xff0c;可以生成一个接口文档&#xff0c;当输入地址 localhost:8101/api/v3/api-docs &#xff08;这…

官宣!Wayland正式支持基于IntelliJ的IDE

对于基于IntelliJ IDE的Linux用户来说&#xff0c;一项令人期待的进步即将到来 – 对 Wayland 显示服务器协议的支持。 这项更新将带来许多好处&#xff0c;包括解决古老的分数缩放问题以及在与适用于 Linux 的 Windows 子系统 (WSLg)&#xff08;在底层运行 Wayland 服务器&am…

高德地图系列(一):vue项目如何使用高德地图、入门以及基本控件使用

目录 第一章 前言 第二章 准备工作 2.1 账号注册 2.2 高德地图开发平台文档 2.3 创建应用 第三章 使用地图 3.1 地图使用步骤 3.2 理解几个地图基础控件 3.3 基础类理解 第一章 前言 小编都是在vue项目中使用高德地图的&#xff0c;每一个功能都会亲测可用之后才会…

大语言模型|人工智能领域中备受关注的技术

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️其他领域】 文章目录 前言关于大语言模型大语言模型是什么&#xff1f;大语言模型有什么用?文案写作知识库回答文本分类代码生成 AWS 如何通过 LLM 提供帮助&#xff1f;Amazon BedrockAmazon SageM…

IDEA软件使用步骤

1.IDEA概述 IDEA全称InelliJ IDEA,是用于java语言开发的集成环境&#xff0c;它是业界公认的目前用于Java程序开发最好的工具。 集成环境&#xff1a;把代码编写&#xff0c;编译&#xff0c;执行&#xff0c;调试扽过多种功能综合到一起的开发工具。 下载&#xff1a;https…

【C语言 | 数组】C语言数组详解(经典,超详细)

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

读书笔记:彼得·德鲁克《认识管理》第21章 企业与政府

一、章节内容概述 企业社会责任最重要的维度之一是政企关系。无论对于企业的顺利运作&#xff0c;还是对于政府的顺利运作&#xff0c;政企关系都至关重要。然而&#xff0c;重商主义典范和宪政主义典范这两种传统理论越来越不适应社会现实&#xff0c;越来越失效。虽然当前尚…

Unity开发之C#基础-异常处理(Try Catch)

前言 其实本来这章应该将栈和队列的 但是后来想想 栈和队列在实际应用很少跟多的是大家了解一下栈和队列的基本常识比如先进先出的是谁后进先出的是谁这种 csdn有很多介绍栈和队列的文章 我觉得都比我理解深刻所以大家可以去搜索参照一下 今天我们继续往下讲解 如何自己主动的…

如何从Android手机恢复已删除的联系人

联系人应该是最重要的信息之一。 如果您不小心从Android手机中删除了联系人&#xff0c;该怎么办&#xff1f; 如果不容易找回丢失的联系人&#xff0c;您可以使用奇客数据恢复安卓版。 从Android的手机中恢复已删除的联系人 只需删除Android联系人&#xff0c;然后您就可以通…

ubuntu中使用 vscode 连接docker开发环境

文章目录 ubuntu中使用 vscode 连接docker开发环境步骤一&#xff1a;安装 Remote Development 插件步骤二&#xff1a;连接远程环境步骤三&#xff1a;开发 问题解决参考连接 ubuntu中使用 vscode 连接docker开发环境 Remote Development 是一个 Visual Studio Code 插件&…

WPF小知识

在编写WPF程序遇到一些小问题&#xff0c;所以记录起来&#xff0c;查其他方便。 Label自动换行 网上搜的都不能自动换行&#xff0c;发现使用Run 就可以。在脚本中直接调用labTip.Text进行赋值就可以了。 <Label Foreground"#FF9E9E9E" FontSize"16"…

Google codelab WebGPU入门教程源码<4> - 使用Uniform类型对象给着色器传数据(源码)

对应的教程文章: https://codelabs.developers.google.com/your-first-webgpu-app?hlzh-cn#5 对应的源码执行效果: 对应的教程源码: 此处源码和教程本身提供的部分代码可能存在一点差异。 class Color4 {r: number;g: number;b: number;a: number;constructor(pr 1.0, …

【hive-解决】HiveAccessControlException Permission denied: CREATEFUNCTION

文章目录 一.任务描述二. 解决 一.任务描述 Error while compiling statement: FAILED: HiveAccessControlException Permission denied: Principal [nameroot, typeUSER] does not have following privileges for operation CREATEFUNCTION [ADMIN PRIVILEGE on INPUT, ADMIN…

华为 Mate 60 Pro 拆解:陆制零件比率上升至47% | 百能云芯

近日&#xff0c;日经新闻联合研究公司Fomalhaut Techno Solutions对华为 Mate 60 Pro 进行了拆解&#xff0c;揭示了这款于8月发布的新型智能手机的成本结构。拆解结果显示&#xff0c;该手机的国产零部件比例达到了47%&#xff0c;相较于三年前的 Mate 40 Pro&#xff0c;提高…

gitlab 12.7恢复

一 摘要 本文主要介绍基于gitlab 备份包恢复gitlab 二 环境信息 科目老环境新环境操作系统centos7.3centos7.6docker19.0.319.0.3gitlab12.712.7 三 实施 主要有安装docker\docker-compose\gitlab 备份恢复三个文件 1.gitlab 配置文件gitlab.rb 2.gitlab 加密文件gitlab-s…

自动化测试面试经历

一家做户外的外企 面试问题 1、自我介绍&#xff1a;大概介绍了自己的工作经历 2、数据库问题&#xff1a;学生表中包含id、姓名、成绩、班级&#xff0c;求平均成绩 回答&#xff1a;group by 班级&#xff0c;求平均&#xff08;不够完美&#xff09; 3、java的访问修饰符…

你不知道的forEach函数

给大家推荐一个实用面试题库 1、前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;web前端面试题库 老实说我不喜欢用forEach&#xff0c;因为它导致的一些bug总是这么不经意&#xff0c;盘点我不喜欢的原因 原因一&…

自动驾驶汽车:人工智能最具挑战性的任务

据说&#xff0c;自动驾驶汽车是汽车行业梦寐以求的状态&#xff0c;将彻底改变交通运输业。就在几年前&#xff0c;对自动驾驶汽车的炒作风靡一时&#xff0c;那么到底发生了什么呢&#xff1f;这么多公司吹嘘到2021年我们将迎来的无人驾驶汽车革命在何处&#xff1f;事实证明…

[ubuntu]ubuntu上安装jdk1.8教程

首先需要去官方网站去下载对应jdk1.8版本&#xff1a; https://www.oracle.com/java/technologies/downloads/ 您也可以去csdn搜索我提供jdk安装包 这里以jdk-8u201-linux-x64.tar.gz为例子&#xff0c;首先下载安装后解压 tar -zxvf jdk-8u201-linux-x64.tar.gz 比如我解…

(论文阅读31/100)Stacked hourglass networks for human pose estimation

31.文献阅读笔记 简介 题目 Stacked hourglass networks for human pose estimation 作者 Alejandro Newell, Kaiyu Yang, and Jia Deng, ECCV, 2016. 原文链接 https://arxiv.org/pdf/1603.06937.pdf 关键词 Human Pose Estimation 研究问题 CNN运用于Human Pose E…