当前位置:首页 > 技术分析 > 正文内容

Java注解的工作原理及如何自定义注解

ruisui885个月前 (01-17)技术分析39

Annotation是Java重要的组成部分,从J2SE 5.0时代就已经存在了。在我们的代码中,我们随处可以看到许多注解,例如@Autowired、@Override、@Service。这些注解我们可能非常熟悉,但是注解的作用、工作原理、工作方式以及我们如何自定义注解,我们可能并不熟悉。这篇文章我们就探索一下这些知识点。

1、什么是注解

注解是一种特殊的元数据,元数据是关于数据的数据,所以,注解就是代码的元数据。我们看下面这个例子:

我们用@Override注解toString()方法,说明我们要重写toString()方法。这里,即使我们不用@Override注解,这个方法任然可以正常执行。那注解的好处是什么呢?@Override告诉编译器,子类要重写这个方法,需要按照自己定义的格式输出内容,也就是覆盖了父类的方法,如果父类中没有这个方法,编译器就会报错。

所以,注解是一种特殊的Java构造器,它可以用于装饰类,方法,字段,参数,变量,构造函数或包。

2、为什么要使用注解

在注释之前(甚至之后),XML被广泛用于元数据。但是随着项目中代码量的增大,XML维护变得越来越麻烦。开发人员希望元数据与代码是紧密耦合,而XML与代码之间的耦合非常松散(在某些情况下,几乎是分开的)。

关于使用注解还是基于XML进行标记一直是一个具有争议的话题,对于开发人员来说,记住以下两个原则即可:

  • 1、假设您要设置一些应用程序范围内的常量。在这种情况下,XML是一个更好的选择,因为它与任何特定的代码段都不相关。
  • 2、如果要将某个方法作为服务公开,则注解将是一个更好的选择,因为它需要与该方法紧密结合。

另一个重要因素是,注解定义了在代码中定义元数据的标准方式。在注解之前,开发人员使用自己的方式定义元数据,这造成元数据定义混乱。但要注解是标准化的东西,更容易维护。

现在,大多数框架都将XML和注解结合使用,以充分利用两者的积极方面。

3、注解的工作方式

注解仅仅是元数据,不包括任何业务逻辑。那它的使用者是谁呢?像@Override这种注解,JVM是它的使用者,它在字节码级别工作。如果我们自己编写了一个注解,那我们就要去实现它的消费者,否则,我们自定义的注解是没有任何作用的。

4、编写自定义注解

在编写自定义注解的时候,我们首先需要搞清楚几个默认的注解,这几个注解仅仅作用与另一个注解之上。

  • @Documented

@Documented注解表明这个注解要被javadoc记录。注解默认状态下是不被javadoc记录的。

  • @Retention

@Documented注解表明该注解保留到那个阶段,主要有三个值:

SOURCE —— 这种注解保留在源代码级别,编译时就会被忽略

CLASS —— 这种注解编译时被保留,在class文件中存在,但JVM将会忽略

RUNTIME —— 这种注解将被JVM保留,利用反射机制可以获取并使用。

  • @Target

@Target注解表明该注解作用的范围。包括package、method、field、构造方法、成员变量、枚举值等属性。

  • @Inherited

@Inherited注解表明该注解是否影响子类。如果定义的注解上使用了@Inherited标记,则使用该注解的某个父类,它的子类默认继承所有的属性

现在我们定义自己的一个注解@CronScheduled

CronScheduled注解上用了三个默认的注解,@interface表明这是一个注解(注意不是接口)。同时我们定义了cron和desc两个属性。这就是一个完整的注解,我们再看怎么使用它。

我们假设一个业务场景:我们的业务中很多个定时任务,这些定时任务我们手动实现了线程池维护并调度这些方法。那在线程池中我们怎么获取那些方法是定时任务呢?这就是自定义注解的作用。我们在synCreative的方法上使用了我们自定义的注解,目的就是让调度的线程池可以发现它。具体的实现看下面代码:

我们循环遍历所有的定时任务方法,并获取方法上的注解,如果方法上有CronScheduled的注解,说明该方法就是定时任务的方法,同时,获取注解上的cron属性值,设定执行任务的周期。

至此,我们就完成了一个自定义的注解。

5、注解用例

注释功能非常强大,Spring和Hibernate之类的框架将注解广泛用于日志记录和验证,在Servlet规范3.0中,引入了许多注解,尤其是与Servlet安全性相关的注释。让我们看看一些常见的注解。

  • HandlesTypes 用于声明传递给的应用程序类的数组ServletContainerInitializer。
  • HttpConstraint 被使用来代表应用于所有HTTP协议方法的安全限制
  • HttpMethodConstraint 特定的安全约束可以应用于不同的请求类型
  • MultipartConfig 声明它的Servlet希望使用multipart / form-data MIME类型进行请求。
  • ServletSecurity 在Servlet实现类上声明此注解,以对HTTP协议请求强制实施安全性约束。
  • WebFilter 用于声明Servlet过滤器的注解。
  • WebInitParam 用于在WebFilter或WebServlet上声明初始化参数。
  • WebListener 在给定的Web应用程序上下文中用于声明各种事件的侦听器。
  • WebServlet 用于声明Servlet的配置。

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/359.html

标签: 注解的作用
分享给朋友:

“Java注解的工作原理及如何自定义注解” 的相关文章

基于Ubuntu的Linux Lite 6.0发行版正式发布

开发者 Jerry Bezencon 今天宣布,基于 Ubuntu 的 Linux Lite 6.0 发行版正式发布。本次更新代号为“Fluorite”,基于 Ubuntu 22.04 LTS (Jammy Jellyfish) 系统,它由长期支持的 Linux 5.15 LTS 内核系列驱动。下载...

亚马逊推出 Amazon Linux 2023 发行版,专为 AWS 云进行优化

稿源:IT之家3 月 19 日消息,本周早些时候,亚马逊宣布推出其第三代 Linux 发行版 Amazon Linux 2023(AL2023)。亚马逊表示,该版本将带来高安全性标准、可预测的生命周期和确定性更新。Amazon Linux 2023 针对 Amazon EC2 进行了优化,与最新的...

高效使用 Vim 编辑器的 10 个技巧

在 Reverb,我们使用 MacVim 来标准化开发环境,使配对更容易,并提高效率。当我开始使用 Reverb 时,我以前从未使用过 Vim。我花了几个星期才开始感到舒服,但如果没有这样的提示,可能需要几个月的时间。这里有十个技巧可以帮助你在学习使用 Vim 时提高效率。1. 通过提高按键重复率来...

2024最新版:前端性能优化方案汇总

前端训练营:1v1私教,终身辅导计划,帮你拿到满意的 offer。 已帮助数百位同学拿到了中大厂 offer。欢迎来撩~~~~~~~~Hello,大家好,我是 Sunday。前端性能优化一直是很多同学非常关注的问题,在日常的面试中也是经常会被问到的点。所以今天咱们就花一点时间来了解一下2024最新的...

虚幻引擎5.5现已发布 手游开发、动画制作重大改进

Epic在今天发布了虚幻引擎5.5,现可通过Epic Launcher下载。此版本在动画创作、渲染、虚拟制片、移动端游戏开发和开发人员迭代工具集等方面做出了重大改进。 官方博客:虚幻引擎5.5现已发布,在动画创作、虚拟制作和移动游戏开发方面取得了显著进步,渲染、摄像机内视觉特效和开发人员迭代等领域的...

USB电池充电基础:应急指南

USB为便携设备供电与其串行通信功能一样,已经成为一种标准应用。如今,USB 供电已经扩展到电池充电、交流适配器及其它供电形式的应用。应用的普及带来的一个显著效果是便携设备的充电和供电可以互换插头和适配器。因此,相对于过去每种装置都采用专用适配器的架构相比,目前的解决方案允许采用多种电源进行充电。毋...