【Java基础】聊聊你不知道的注解那些事

在实际的开发中,我们大量使用了注解,无论是spring、还是本身jdk提供的,注解都是围绕一个java程序员的开发生活,所以本篇主要介绍注解相关的概念、理论、实践。

定义注解

注解和异常非常相似,都可以自定义,但是我们自定义异常的场景比较多,但是注解就比较少。
overrider是本身jdk提供的,表示当前方法被覆盖的描述。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

我们自定义一个限流注解。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RateLimit {public enum TimeUnit {SECOND,MINUTE,HOUR,DAY,MONTH}String apiName();int limitCount();TimeUnit timeUnit() default TimeUnit.SECOND}

target

target用来描述注解的使用范围,

public enum ElementType {TYPE, // 类型 类,接口,枚举FIELD, // 用于成员变量METHOD, // 用于方法PARAMETER, // 用于参数CONSTRUCTOR, // 用于构造方法LOCAL_VARIABLE, // 局部变量ANNOTATION_TYPE, PACKAGE, // 用于包TYPE_PARAMETER,TYPE_USE
}

一般主要常用的就是针对类、方法、成员变量。实际上注解只是一个标识作用。可以通过反射访问的代码元素,我们都可以通过注解标识。如果不使用target标识使用范围,默认就是做任何范围。

Retention

描述注解的可见范围,生命周期。

public enum RetentionPolicy {SOURCE, // 源码中可见CLASS, RUNTIME
}

SOURCE代表仅在源码中可见,当编译器将源代码编译为字节码后,注解信息将被丢弃。不过编译器可以在可见范围内查找,比如override 查找其父类是否有对应的方法,没有就编译错误。class标识在字节码范围。runtime标识在运行时期。
源码->编译->运行时。

Documented

标识在java doc中进行输出

interface

class 代表类 interface 代表接口、enum代表枚举类、@interface代表注解。

标记注解

标记注解,其实就是使用不同的注解,放在方法或者类上。

    @RateLimit(apiName = "/user/info",limitCount = 1000,timeUnit = RateLimit.TimeUnit.SECOND)public void getUserInfo() {   }

读取注解

定义注解、标记注解,还需要进行读取注解,也就是说需要通过响应逻辑的代码处理。对于java内建注解,编译器和JVM都可以对其进行读取和处理,比如override注解,编译器在编译代码时,会读取所有标记了@override的方法,并且检查父类中是否有同名方法。没有就编译报错。

对于自定义注解,需要我们开发相应的读取和处理逻辑,如何来读取代码中的注解信息。就需要使用上一节课中的反射语法。反射其实是作用于代码运行时。

注解应用

最常见的就是 替换配置文件
在这里插入图片描述
spring中配置文件 一般通过xml进行定义,我们可以使用注解替代xml配置
在这里插入图片描述
那么spring容器时如何使用注解的?
在程序启动的时候,spring ioc容器利用反射获取到appConfig配置, 发现包含@configuration注解,便确定这个类时一个配置类。通过反射获取到对应方法的bean对象,并创建对应的对象,存储到一个大map中,key 为beanName value为对象,就可以通过getBean获取对象。
而平时常见的@service、@controller、@respository 都是同样的方式。

应用场景

自定义注解 csv文件
比如在实际的开发中,我们需要对一个对象的字段进行写入到csv文件中,但是有一些字段不想被写入。比如用户的基本信息(ID、name、age、phone、idcardnum、住址信息等),比如针对phone、和idcardnum 需要我们进行脱敏处理。或者忽略不写。 我们可以开发一个自定义注解。

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface CsvIgnore {
}
    @CsvIgnoreprivate String phone;

通过反射的方式在公共的csv文件操作逻辑进行忽略。这样其实就做到了透明化。使用者其实不用关心。

    CsvIgnore ignoreProperty = field.getAnnotation(CsvIgnore.class);if (!Objects.isNull(ignoreProperty)) {csvIgnoreSet.add(field.getName());}

自定义主从切换
在实际的开发中,我们可能有多个DB要切换操作,比如读取风控数据库、后台数据库、用户数据库等,如何在同一个请求中自定义获取数据源。我们可以通过注解的方式。通过AOP的方式

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSourceHolder {DataSource value() default DataSource.SALVE;
}
 @Around("@annotation(dataSourceHolder)")public Object enhance(ProceedingJoinPoint joinPoint, DataSourceHolder dataSourceHolder) {if (dataSourceHolder.value() == DataSource.MASTER) {DynamicDataSourceHolder.setDataSourceTypeMaster();} else {DynamicDataSourceHolder.setDataSourceTypeSlave();}Object proceed = null;try {proceed = joinPoint.proceed();} catch (Throwable throwable) {throw new RuntimeException(throwable);} finally {DynamicDataSourceHolder.clearDataSourceType();}return proceed;}

在这里插入图片描述

小结

好了本篇主要详细介绍了java注解的相关使用,原理,关于如何获取注解,需要等下一篇的关于反射的讲解。以后写注解就知道为什么加一个@service就可以被扫描成bean对象使用,以及如何定义注解在 自己的项目中使用。

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

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

相关文章

如何在html5中的canvas绘制文本自动换行?

在这篇文章中我们讲解了怎么解决canvas绘图过程中,drawText的换行问题,先看一个大家平时在canvas绘制文本都会遇到的问题: 一个150*100的canvas画布,加个边框明显边界 <canvas id="canvas" style="border:solid 1px darkgoldenrod;" width="2…

ubuntuNginx反向代理和负载均衡

配置两台服务器确保nginx启动并且可以访问 配置nginx代理服务器 可以选择直接安装或者编译安装nginx rootubuntu:~# apt install libgd-dev #安装依赖 rootubuntu:~# apt update rootubuntu:~# apt install libpcre3 libpcre3-dev rootubuntu:~# apt-get install openssl…

前端代码审查(Code Review)---具体实践规范会持续更新

前端代码审查&#xff08;Code Review&#xff09; 针对目录结构、SCSS规范、JS规范、Vue规范 可参照官方给出的风格指南&#xff08;Code Review&#xff09; 具体实践规范 1、POST/PUT/DELETE 请求按钮需要添加 loading 状态&#xff0c;防止重复提交。 建议使用 Element UI…

jQuery遍历(其他遍历)

1、.add&#xff08;&#xff09;: 添加元素到匹配的元素集合 例一&#xff1a; <script> $(document).ready(function(){ $("div").add("p").css("background-color","red") }) </script…

前端canvas项目实战——简历制作网站(二)——右侧属性栏(颜色)

目录 前言一、效果展示二、实现步骤1. 实现一个自定义的选色板2. 创建属性工厂&#xff0c;为每个对象定制属性3. 为canvas对象注册监听器&#xff0c;点击不同对象时更新属性列表 三、Show u the code后记 前言 上一篇博文中&#xff0c;我们实现了左侧工具栏&#xff0c;通过…

kubernetes实战教程:kubernetes简介

kubernetes实战教程:kubernetes简介 简介 官网:https://kubernetes.io/zh-cn/ 一款生产级别的容器编排系统,也成为k8s,用于自动部署,扩展和管理容器化应用的开源系统.Google在2014年开源了kubernetes(后续就用k8s来代替了)这个项目.k8s建立在Google大规模运行生产工作负载十几…

解决vue 2.6通过花生壳ddsn(frp内网穿透)实时开发报错Invalid Host header和websocket

请先核对自己的vue版本&#xff0c;我的是2.6.14&#xff0c;其他版本未测试 起因 这两天在维护一个基于高德显示多个目标&#xff08;门店&#xff09;位置的项目&#xff0c;由于高德要求定位必须使用https服务&#xff0c;遂在本地无法获取到定位坐标信息&#xff0c;于是…

当一个json存在id 和_id 的时候,使用JSONObject.parseObject进行序列号操作,映射错误

FastJson默认会将Java对象中的下划线风格的字段名转换为驼峰风格的属性名。如果你想保留原始的下划线风格的字段名&#xff0c;可以在对应的字段上添加JSONField注解&#xff0c;并设置其name属性为下划线风格的字段名。 {"hasExtraBed":0,"hasWindow":2,&…

OpenCV笔记之图像处理中遮罩和掩模的关系

OpenCV笔记之图像处理中遮罩和掩模的关系 code review 文章目录 OpenCV笔记之图像处理中遮罩和掩模的关系1.遮罩详解遮罩的创建遮罩的应用遮罩的主要应用遮罩的类型如何创建遮罩遮罩在图像处理中的应用方式 2.遮罩和掩模的关系 1.遮罩详解 在图像处理中&#xff0c;遮罩&#…

字符串和格式化输入/输出

本文参考C Primer Plus进行C语言学习 文章目录 strlen()函数sizeof使用数据类型 1.strlen()函数 之前提到的sizeof运算符它以字节为单位给出对象的大小。strlen()函数给出字符串中的字符长度。 #include<stdio.h> #include<string.h> #define PRAISE "You ar…

IS-IS:05 ISIS开销值和协议优先级

IS-IS 协议为路由器的每个 IS-IS 接口定义并维护了一个 level-1 开销值和一个 level-2开销值。开销值可以在接口上或者全局上手动配置&#xff0c;也可以使用 auto-cost自动计算确定。 修改接口cost&#xff1a; int g0/0/0 isis cost 50修改全局cost&#xff1a; isis cir…

Github 无法正常访问?一招解决

查询IP网址: https://ip.chinaz.com/ 主页如下&#xff1a; 分别查询以下三个网址的IP&#xff1a; github.com github.global.ssl.fastly.net assets-cdn.github.com 修改 hosts 文件&#xff1a; 将 /etc/hosts 复制到 home 下 sudo cp /etc/hosts ./ gedit hosts 在底下…

实现成本最优的一体化管理,新一代数据平台的建设方式丨爱分析调研

导读 1.当前&#xff0c;企业在大数据和数据中台建设上取得成果&#xff0c;但数据开发管理仍具挑战性&#xff08;成本、效率、复杂度&#xff09;。 2.随数据平台领域成熟&#xff0c;厂商应结合自身需求&#xff0c;重新思考“基于开源自建数据平台”的重资产模式与“购买云…

【C语言】(3)字符

字符串 1. 字符串简介 在C语言中&#xff0c;字符串是由字符数组构成的序列&#xff0c;以空字符&#xff08;\0&#xff09;结尾。这个空字符不可见&#xff0c;用于标记字符串的结束。C语言中没有专门的字符串类型&#xff0c;通常使用字符数组表示字符串。 2. 声明和初始…

ARP攻击防范

概念 ARP(Address Resolution Protocol)安全是针对ARP攻击的一种安全特性,它通过一系列对ARP表项学习和ARP报文处理的限制、检查等措施来保证网络设备的安全性。ARP安全特性不仅能够防范针对ARP协议的攻击,还可以防范网段扫描攻击等基于ARP协议的攻击。 ARP泛洪攻击 1)A…

swift 进阶知识点

本文的知识点会比较散&#xff0c;是基础语法之外的一些进阶内容&#xff0c;如果有写的不妥的地方&#xff0c;欢迎评论区指正&#xff5e; Optional 可选值是通过枚举实现的&#xff1a; enum Optional<Wrapped> {case nonecase some(Wrapped)对于Optional<Wrapp…

React中实现虚拟加载滚动

前言&#xff1a;当一个页面中需要接受接口返回的全部数据进行页面渲染时间&#xff0c;如果数据量比较庞大&#xff0c;前端在渲染dom的过程中需要花费时间&#xff0c;造成页面经常出现卡顿现象。 需求&#xff1a;通过虚拟加载&#xff0c;优化页面渲染速度 缺点&#xff1a…

Facebook 广告帐户:多账号运营如何防止封号?

Facebook目前是全球最受欢迎的社交媒体平台之一&#xff0c;拥有超过27亿活跃用户。因此&#xff0c;它已成为个人和企业向全球受众宣传其产品和服务的重要平台。 然而&#xff0c;Facebook 制定了广告商必须遵守的严格政策和准则&#xff0c;以确保其广告的质量和相关性&…

一文搞懂Jenkins持续集成解决的是什么问题

1、持续集成的定义 大师 Martin Fowler 是这样定义持续集成的: 持续集成是一种软件开发实战, 即团队开发成员经常集成他们的工作. 通常, 每个成员每天至少集成一次, 也就意味着每天可能发生多次集成. 持续集成并不能消除Bug, 而是让它们非常容易发现和改正. 根据对项目实战的…

redis面试题合集-基础

前言 又来到每日的复习时刻&#xff0c;昨天我们学习了mysql相关基础知识&#xff0c;还有分布式数据库介绍&#xff08;后续总结时再持续更新&#xff09;。今日继续学习缓存杀器&#xff1a;redis redis基础面试题合集 什么是Redis&#xff1f; Redis是一个开源的、内存中…