java方法体逻辑不会写怎么办,想自己写框架?不会写Java注解可不行

2dae860d8c98974debb7a5ea194dd4d8.png

用注解一时爽,一直用一直爽

Java后端开发进入spring全家桶时代后,开发一个微服务提供简单的增删改查接口跟玩泥巴似的非常简单,一顿操作猛如虎,回头一看代码加了一堆注解:@Controller @Autowired @Value,面向注解编程变成了大家不可缺少的操作。

想象一下如果没有注解Java程序员可以要哭瞎😭

既然注解(annotation)这么重要,用的这么爽,那注解的实现原理你知道么?我猜你只会用注解不会自己写注解(手动滑稽)。

好了,下面的内容带大家从零开始写一个注解,揭开注解神秘的面纱。

原来注解不神秘

注解用大白话来说就是一个标记或者说是特殊的注释,如果没有解析这些标记的操作那它啥也不是。

注解的格式如同类或者方法一样有自己特殊的语法,这个语法下文会详细介绍。

那如何去解析注解呢?这就要用到Java强大的反射功能了。反射大家应该都用过,可以通过类对象获取到这个类的各种信息比如成员变量、方法等,那注解标记能不能通过反射获取呢?当然可以了。

所以注解的原理其实很简单,本质上是通过反射功能动态获取注解标记,然后按照不同的注解执行不同的操作,比如@Autowired可以注入一个对象给变量赋值。

看到这里是不是很躁动啊,来吧自己也撸一个注解。

造火箭啦,自己动手写一个注解

便于大家理解,这里先引入一个场景:在线教育火了,经理让我写一个模块实现学生信息管理功能,考虑到分布式并发问题,经理让我务必加上分布式锁。

经理问我几天能搞定?我说至少3天。如是脑补了以下代码:

2d8ce1a066a83db6e46b35b9b8000d2a.png

未使用注解前

经理走后我在思考,我能不能只花一天时间写完,剩下两天时间用来写博客划水呢?突然灵感来了,我可以把重复的代码逻辑抽出来用注解实现不就节省代码了,哈哈,赶紧写。

使用注解之后整个方法清爽了很多,HR小姐姐都夸我写的好呢。

d5ee6f175f6b9850b7d6a59e18c4aaf6.png

使用注解后

代码已经写完上库了,现在我在划水写博客呢。是不是很简洁很优雅很牛逼,怎么做到的呢,主要分为三步:1打开冰箱门,2把大象放进去,3把冰箱门关好。好了,扯远了,大家接着往下看。

第一步定义一个注解

900e46b6522fae86dfaefca4ec45885b.png

注解的三大组成部分

一个注解可以简单拆解为三个部分:

第一部分:注解体

注解的定义有点类似于接口(interface),只不过前面一个加了一个@符号,这个千万不能省。

第二部分:注解变量

注解变量的语法有点类似于接口里面定义的方法,变量名后面带一对括号,不同的是注解变量后面可以有默认值。另外返回值只能是Java基本类型、String类型或者枚举类,不可以是对象类型。

第三部分:元注解

元注解(meta-annotation)说白了就是给注解加注解的注解,是不是有点晕了,这种注解是JDK提前内置好的,可以直接拿来用的。不太懂也没有关系反正数量也不多,总共就4个,我们背下来吧:@Target @Retention @Documented @Inherited

Target注解

用来描述注解的使用范围,即被修饰的注解可以用在什么地方 。

注解可以用于修饰 packages、types(类、接口、枚举、注解类)、类成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数),在定义注解类时使用了@Target 能够更加清晰的知道它能够被用来修饰哪些对象,具体的取值范围定义在ElementType.java 枚举类中。

比如上面我们写的Redis锁的注解就只能用于方法上了。

Retention注解

用来描述注解保留的时间范围,即注解的生命周期。在 RetentionPolicy 枚举类中定义了三个周期:

public enum RetentionPolicy {

SOURCE, // 源文件保留

CLASS,  // 编译期保留,默认值

RUNTIME // 运行期保留,可通过反射去获取注解信息

}

像我们熟知的@Override注解就只能保留在源文件中,代码编译后注解就消失了。比如上面我们写的Redis锁的注解就保留到了运行期,运行的时候可以通过反射获取信息。

Documented注解

用来描述在使用 javadoc 工具为类生成帮助文档时是否要保留其注解信息,很简单不多解释了。

Inherited注解

被Inherited注解修饰的注解具有继承性,如果父类使用了被@Inherited修饰的注解,则其子类将自动继承该注解。

好了,这一步我们已经将注解定义好了,但是这个注解如何工作呢?接着看。

第二步实现注解的业务逻辑

在第一步中我们发现定义的注解(@EnableRedisLock)中没有业务逻辑,只有一些变量,别忘了我们的注解是要使能Redis分布式锁的功能,那这个注解到底是怎么实现加锁和释放锁的功能呢?这个就需要我们借助反射的强大功能了。

fcaf03512db611cda261b8594af7db1a.png

注解的操作

这里借助了切面的功能,将EnableRedisLock注解作为一个切点,只要方法上标注了这个注解就会自动执行这里的代码逻辑。

通过反射机制拿到注解对象后就可以执行加锁解锁的常用逻辑啦。Redis实现分布式锁相信大家已经很熟悉了,这里就不在啰嗦了。

第三步在业务代码中尽情的使用注解

@EnableRedisLock(lockKey = "student", expireTime = 10, timeUnit = TimeUnit.SECONDS, retryTimes = 5)

public void method1(Student student){

// 这里写业务逻辑

}

在需要加锁的方法上直接加上注解就可以啦,怎么样是不是很简单呀,赶紧在你的项目中运用起来吧。

好了,自己写一个注解的内容就介绍到这里了,学会了吗?

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

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

相关文章

联想拯救者y7000加内存条_短测联想拯救者Y7000,到底值不值得买?

7000块左右的笔记本电脑有什么好选择,我相信这是很多人一直纠结的问题,虽然我用过的笔记本很多,但是这个价位的用的少之又少,但随着十代酷睿标压处理器的大量铺货,联想拯救者Y7000进入了我的视线。那到底值不值得买呢&…

php适用于什么服务器,php – 找不到laravel类(适用于localhost但不适用于DO服务器)...

这是一个重复的问题 – 例如:Laravel 4 migrations – class not found但是,我已经尝试了所有解决方案(来自我能找到的每个论坛)并且无法解决这个问题.脚本我在我的本地机器上创建了一个Laravel 4项目 – 添加了一些类,控制器,视图等 – 项目运行良好.然后我将这个新…

python扫雷游戏课程设计小组任务计划与分配表_python实现扫雷游戏

本文为大家分享了python实现扫雷游戏的具体代码,供大家参考,具体内容如下本文实例借鉴mvc模式,核心数据为model,维护1个矩阵,0表无雷,1表雷,-1表已经检测过。本例使用python的tkinter做gui,由于…

时间同步服务器java,Windows 配置时间同步服务器以及配置时间同步间隔

如何修改windows下的时间同步间隔操作步骤如下:打开注册表:在“开始”菜单→“运行”项下(或按WinR)输入“Regedit”进入注册表编辑器。2.修改默认时间服务器IP:展开HKEY_LOCAL_MACHINE->SYSTEM->CurrentControlSet->Services->W…

房价python爬取_python爬取并解析 重庆2015-2019房价走势

1 #! /usr/bin/env python2 #-*- coding:utf-8 -*-34 5 Created on 2019年11月24日67 author: Admin8 910 importrequests11 from lxml importetree12 importtime13 importcsv1415 16 方法名称:spider17 功能: 爬取目标网站,并以源码文本18 参…

PHP递归删除目录面试题,PHP 递归删除目录中文件

/*** 递归删除目录中文件* param $pathname* return bool*/public static function delDir($pathname)//要删除的目录{if(file_exists($pathname)) {if(is_file($pathname)) {unlink($pathname);} else {$dir opendir($pathname);while($filename readdir($dir)) {if($filena…

python中 12_python编程中常用的12种基础知识总结

1、正则表达式替换目标: 将字符串line中的 overview.gif 替换成其他字符串>>> line >>> more.compile(r(?<SRC)"([\w\.])",re.I)>>> mo.sub(r"\1****",line)>>> mo.sub(rreplace_str_\1,line)< /span>>&…

php smarty分页原理,SMARTY分页详解

<?phprequire_once (include/common.inc.php);//这里是个接口common.inc.php里面包函了一些常用到的函数类库以及SMARTYinclude_once(header.php);//调用头部信息,SESSION的信息全都保存在这里,这样做的好处是几乎所有的页面都不需要在开头输入session_start();$smarty new…

python十个一行_python 如何将一系列数字十个一行输出

展开全部答案如下&#xff1a;代码详解1、使用循环输出列表&#xff0c;利用 计数器控制输出数量&#xff0c;当输出到第十个&#xff0c;62616964757a686964616fe4b893e5b19e31333365663532计数器归零&#xff0c;重新开始计数2、print输出增加end参数可以控制输出后以什么结尾…

sql oracle 递归查询语句,Oracle使用SQL语句进行递归查询

idpid问题描述&#xff1a;102031415262738495取出id为1及其下属的所有的数据,结果为下idpid1031417384SQL> CREATE TABLE TBL_TEST2 (3 ID NUMBER,4 NAME VARCHAR2(100 BYTE),5 PID NUMBER DEFAULT 06 );Table createdS…

python中与0xf2相等的是_python中__str__与__repr__

(1)背景python中&#xff0c;对于类(自定义类)的实例对象的默认显示既没有太大用处&#xff0c;也不美观。比如&#xff1a;1 classadder:2 def __init__(self,value0):3 self.datavalue #初始化数据4 def __add__(self,other):5 self.dataother6>>> xadder()7>>…

oracle清理asm归档日志,【Oracle】 rman 删除归档日志的命令

因为数据仓库上asm的磁盘空间不足&#xff0c;需要删除早期的归档日志&#xff0c;查看资料有以下两种方式&#xff1a;delete archivelog until time sysdate-N;delete archivelog all completed before sysdate-N;这两个命令的差别在哪里呢&#xff1f;使用list 命令来查看一…

求逆矩阵计算器_991CN的矩阵运算

昨天的推文中说了一道二端口的题目&#xff0c;虚线中的大二端口由两个小二端口级联而成&#xff0c;在计算过程中&#xff0c;我们需要使用到矩阵的运算&#xff0c;昨天讲题的时候说会说一下用计算器进行矩阵运算&#xff0c;今天我们就来说一下。其实在算电路的时候&#xf…

去快捷方式小箭头_电脑桌面如何快速去掉快捷方式小箭头

我们使用电脑时会发现在电脑桌面图标上经常有一个小箭头&#xff0c;这是什么原因呢&#xff1f;原来&#xff0c;这个小箭头只存在于快捷方式的软件图标上&#xff0c;就是说通过快捷方式创建的图标就有这个小箭头。那么如何去掉这些小箭头呢&#xff01;不知道也没关系&#…

Oracle里silent,静默方式(silent)安装Oracle软件

有的时候不方便登陆Linux/Unix的图形界面安装数据库&#xff0c;且GUI方式安装让我们无法知道具体是做了什么操作&#xff0c;我们完全可以采用命令模式安装和删除Oracle软件(代替OUI)、建立和删除数据库库(代替dbca)。平台&#xff1a;RHEL4.5&#xff0c;Oracle10.2.0.11、上…

oracle 移动日志文件,Oracle数据库移动数据文件、日志文件和控制文件

1、关闭数据库SQL> shutdown immediate;2、移动数据文件和日志文件到新位置SQL> host mv /u01/olddata.dbf /u02/newdata.dbf;SQL> host mv /u01/oldredo.log /u02/newredo.log;3、以加载模式启动数据库SQL> startup mount;4、在数据库中更改数据文件和日志文件路径…

python3导入_Python3导入相对还是绝对的正确方法?

我正在编写一个python模块。在Python2中一切正常&#xff0c;但在Python3中&#xff0c;导入失败。这是我的代码结构。neuralnet/__init__.pytrain.py # A wrapper to train (does not define new things)neuralnet.py # Defines the workhorse class neuralnetlayers/__init__…

oracle pdb是什么意思,浅谈Oracle数据库12c PDB技术

PDB大致功能描述&#xff1a;创建&#xff1a;用create pluggable database的命令&#xff0c;用file_name_convert的方式拷贝seed pdb的文件到对应的新pdb的路径下。拷贝的是最基本system和sysaux表空间&#xff0c;将新建的pdb从mount的状态打开到read write的状态。建立pdb用…

oracle查询sql时间ain,Oracle SQL 时间查询

一、在使用Oracle的to_date函数来做日期转换时&#xff0c;很多Java程序员也许会和我一样&#xff0c;直觉的采用ldquo;yyyy-MM-dd HH:mm:ssrdquo;的to_date()与24小时制表示法及mm分钟的显示&#xff1a;一、在使用Oracle的to_date函数来做日期转换时&#xff0c;很多Java程序…

室内定位算法_001:室内定位算法技术咨询服务工作室简介(更新)

点击蓝字关注我们团队成员&#xff1a;何博士(中国科学院大学&#xff0c;博士) 杨博士(加拿大多伦多大学&#xff0c;博士后)微信联系号&#xff1a;UWB_cwhe服务模式&#xff1a;1. 为企业提供定位算法技术支持与指导&#xff0c;以提高企业室内定位系统产品的稳定…