Java注解的入门学习

news2024/12/25 10:21:54

一、概念

Java注解是一种元数据形式,可以被添加到Java代码中的各种元素(类、方法、字段等)上,以提供关于这些元素的额外信息。注解是在Java 5中引入的一项特性,它们不直接影响代码的执行,而是提供了一种机制来对代码进行标记和解释。

通常以@符号开头,放到注解目标的前面。Java提供了一些内置的注解。

@Override:该注解代表重写父类的方法

@Deprecated:使用@Deprecate的方法会出现一条删除线,表示该方法过时了,但是不影响使用

@SuppressWarning:指示编译器去忽略注解中声明的警告

@Retention:标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问

@Documented:标记这些注解是否包含在用户文档中

@Target:标记这个注解应该是哪种 Java 成员。

@Inherited:标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)

从 Java 7 开始,额外添加了 3 个注解:

@SafeVarargs:忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告

@FunctionalInterface:Java 8 开始支持,标识一个匿名函数或函数式接口。

@Repeatable:Java 8 开始支持,标识某注解可以在同一个声明上使用多次。

二、注解的作用

1. 提供元数据信息

注解为代码元素提供了额外的元数据信息。这些信息可以用于在编译时或运行时进行处理,以实现各种功能。例如,@Override注解用于标记方法覆盖父类的行为,这在编译时会进行检查。

2.编译时检查

使用注解可以在编译时进行静态检查,从而帮助捕获一些常见的错误。例如,使用@Deprecated注解标记已过时的方法或类可以在编译时产生警告,提醒开发人员使用更合适的替代方案。

3.自动生成代码

注解可以用于生成一些重复性的代码,从而减少开发人员的工作量。通过编写自定义的注解处理器,可以在编译时根据注解信息生成额外的代码。这在一些框架和库中被广泛使用,以提供更便捷的开发方式。

4. 运行时处理

通过使用反射机制,可以在运行时处理注解信息。这样可以实现一些动态的行为,例如根据注解信息加载特定的配置文件或执行特定的逻辑。

三、自定义注解

创建自定义的注解,我们需要使用到下面几个注解,这些作用于注解上的注解我们称为元注解。

1.Target注解

标记这个注解应该是哪种 Java 成员使用。

TYPE:类、接口(包括注释类型)或枚举声明
FIELD:字段声明(包括枚举常量)
METHOD: 方法声明
PARAMETER: 参数声明
CONSTRUCTOR: 构造方法声明
LOCAL_VARIABLE: 局部变量声明
ANNOTATION_TYPE:释类型声明
PACKAGE:包声明

2.Retention注解

标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。

source:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;被编译器忽略。
class:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期。
runtime:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在。

3.@Document注解

@Document注解用于指定被修饰的注解可以被javadoc工具提取成文档。定义注解类时使用@Document注解进行修饰,则所有使用该注解修饰的程序元素的API文档中将会包含该注解说明

4.@Inherited注解

@Inherited注解指定注解具有继承性,如果某个注解使用@Inherited进行修饰,则该类使用该注解时,其子类将自动被修饰

5.@Repeatable注解

@Repeatable注解是Java8新增的注解,用于开发重复注解。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: 自定义注解
 */
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    // 定义一个名为“name”的注解元素,默认为空字符串
    String name() default "";

    // 定义一个名为"value"的注解元素,默认值为0
    int value() default 0;

}

我们创建一个注解测试类,获取使用自定义注解的信息。

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: 自定义注解测试
 */
@MyAnnotation(name = "class", value = 10)
public class AnnotationTest {
    public static void main(String[] args) {
        // 获取类上的自定义注解数据
        MyAnnotation myAnnotation = AnnotationTest.class.getAnnotation(MyAnnotation.class);
        System.out.println("name:" + myAnnotation.name() + ",value=" + myAnnotation.value());

        // 获取方法上的自定义注解数据
        Class<AnnotationTest> aClass = AnnotationTest.class;
        Method[] methods = aClass.getDeclaredMethods();
        for (Method method : methods) {
            Annotation[] annotations = method.getDeclaredAnnotations();
            for (Annotation annotation : annotations) {
                MyAnnotation testAnnotation = (MyAnnotation) annotation;
                System.out.println("name:" + testAnnotation.name() + ",value=" + testAnnotation.value());
            }
        }
    }

    @MyAnnotation(name = "method", value = 5)
    private static void show() {
        System.out.println("方法");
    }
}

执行程序结果:

name:class,value=10
name:method,value=5

四、自定义注解在web里的使用

在web开发中,权限控制非常重要,所以有些接口会限制必须登录之后才能访问,但是个别接口并没有这种限制。

1.我们自定义一个注解,用于标记需要登录后才能访问。

import java.lang.annotation.*;

/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: 自定义注解标记访问方法需要登录
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NeedLoginAnnotation {
}

2.创建一个拦截器,用于处理我们的自定义登录注解

import com.example.quartzdemo.annotation.NeedLoginAnnotation;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: 自定义登录拦截器
 */
public class LoginFilter implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) {
        if (obj instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) obj;
            // 判断方法是否使用了自定义登录注解  
            NeedLoginAnnotation needLoginAnnotation = handlerMethod.getMethod().getDeclaredAnnotation(NeedLoginAnnotation.class);
            if (needLoginAnnotation != null) {
                System.out.println("该接口需要登录后才能访问");
                // 判断是否登录的逻辑 如果是登录状态就放行..
                return false;
            }
        } else if (obj instanceof ResourceHttpRequestHandler) {
            return true;
        }
        // 放行
        return true;
    }
}

3.把我们创建的拦截器添加到web配置中

import com.example.quartzdemo.filter.LoginFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: web配置
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 添加自定义拦截器
        registry.addInterceptor(new LoginFilter())
                .addPathPatterns()
                .excludePathPatterns("/","/login");
    }
}

4.创建控制层进行测试

import com.example.quartzdemo.annotation.NeedLoginAnnotation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: 自定义注解测试
 */
@RestController
public class AnnotationController {

    /**
     * 新增 加上了需要登录才能访问的注解
     */
    @RequestMapping("/save")
    @NeedLoginAnnotation
    public String toSave() {
        System.out.println("新增操作");
        return "新增";
    }

    /**
     * 查询
     */
    @GetMapping("/find")
    public String toFind() {
        System.out.println("查询操作");
        return "查询";
    }
}

在新增操作的时候我们标记了需要登录才能访问的注解,在查询的接口我们没有添加这个注解。

 控制台返回 

该接口需要登录后才能访问

这样我们就实现了标记自定义登录注解的方法,如果没有登录的情况下是不能访问的。

我们在访问查询的接口,因为查询的接口没有添加自定义的登录注解,所以拦截器是放行的,是可以访问这个方法。

 

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

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

相关文章

顺序表算法练习

一.顺序表基础算法 1.说明 博主这里是算法练习&#xff0c;帅气的读者来这里默认已经知道了它&#xff0c;这里主要是针对408考研真题中关于线性表的算法题进行编写。第一部分是根据课本编写线性表的基本函数&#xff0c;剩下四个部分是针对考研真题的算法练习。 2.C语言代码…

ChatGLM的模型架构

ChatGLM的部署微调等&#xff0c;很多资料&#xff0c;不再赘述。 P-tuning V2 以P-Turing V2为例&#xff0c;介绍ChatGLM的网络结构。P-tuning V2方法训练时冻结模型的全部参数&#xff0c;只激活prefix_encoder的参数。 1、prefix encoder 初始化pre_len&#xff0c;代表…

Apple pencil平替哪款好?平价电容笔测评

现今&#xff0c;使用电容笔的人越来越多&#xff0c;各大品牌厂商对电容笔各种性能的设计也愈发用心。那么&#xff0c;电容笔哪个品牌好用呢&#xff1f;下面&#xff0c;我来给大家推荐几款质量好的Apple pencil平替&#xff0c;需要的小伙伴可以当个参考。 一、如何挑选到…

Vue3+TS+Vite开发组件库并发布到npm

Vue2开发插件并发布到npm 使用VitePress静态网站生成器创建组件库文档网站并部署到GitHub 目标&#xff1a;创建 vue-amazing-ui 组件库 &#xff0c;并发布到npm 该组件库已发布到 npm&#xff0c;直接安装即可使用&#xff1a; pnpm i vue-amazing-ui #or yarn add vue-a…

(十一)K8S可视化工具Rancher学习、安装

1.Rancher背景概述 在过去几年中&#xff0c;容器技术如 Docker 和容器编排引擎如 Kubernetes 受到了广泛关注和采用&#xff0c;它们为应用程序的部署、可扩展性和管理带来了革命性的变化。 然而&#xff0c;随着容器技术的快速发展&#xff0c;容器集群的管理和操作变得越来…

【笔试强训选择题】Day21.习题(错题)解析

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;笔试强训选择题 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01; 文章目录 前言 一、…

hadoop搭建、mysql、hive部署

写在前面&#xff1a; 本篇文章基于linux系统Centos7环境下进行搭建、操作 仅作为学习参考借鉴&#xff0c;欢迎大家交流学习&#xff01;一、 HDFS安装搭建 1.1 关闭虚拟机防火墙 在之后的学习、操作中&#xff0c;经常会遇到在宿主机中通过程序去访问虚拟机中的相关软件&am…

再获肯定!Coremail入选2023网络空间安全大会优秀案例!

6月2日-3日&#xff0c;在中国电子学会主办的“2023网络空间安全大会”上&#xff0c;由广东盈世计算机科技有限公司申报的“Coremail邮件安全解决方案”获评2023网络空间安全大会优秀案例&#xff0c;再次获得行业权威认可&#xff01; 本次大会由中国电子学会主办&#xff0c…

hudi系列-append写过程

前言 Append模式每次都生成新的parquet文件,不涉及数据修改、去重。cow+insert一直是append模式,mor+insert在0.13.1后也统一走append写流程(HUDI-6045) 在0.13.1之前,mor+insert存在着写parquet和写log两种情况: 写parquet:compaction.schedule.enabled = false & …

Loadrunner和JMeter、Locust三款性能测试工具全面对比

随着软件技术的发展&#xff0c;软件应用越来越普遍&#xff0c;不仅仅是互联网大厂的应用需要进行性能测试了&#xff0c;就连一些中小型的互联网应用也越来越需要对软件项目进行性能测试了。所以本文就将通过Loadrunner、JMeter和Locust三款性能测试工具从以下几个方面进行介…

QML学习二:Doxygen为qml工程生成代码文档

效果如下: 设置后能够支持.js和.qml文档。 QML学习二:Doxygen为工程生成注释文档 前言一、安装doxyqml二、Doxygen设置1.文档目录设置2.文档目录设置三、添加注释总结前言 好的代码必须配一个好的文档说明,方便以后维护以及学习。 前提条件: 1.安装好了Doxygen代码生成工…

快速搭建,降低成本!了解低代码平台适用的五大场景

对于希望简化应用程序开发流程的公司来说&#xff0c;低代码平台已经成为一种有效的解决方案。这些平台使创建和部署应用程序成为可能&#xff0c;而不需要广泛的编码技能或知识&#xff0c;从而使过程更快、更高效、更具成本效益。但是&#xff0c;低代码平台适用于哪些场景呢…

《操作系统》by李治军 | 实验6 - 信号量的实现和应用

目录 一、实验目的 二、实验内容 &#xff08;一&#xff09;用信号量解决生产者—消费者问题 &#xff08;二&#xff09;实现信号量&#xff0c;用生产者—消费者程序检验 三、实验准备 1、信号量 2、多进程共享文件 3、终端也是临界资源 4、原子操作、睡眠和唤醒 …

接口测试 —— 接口测试定义

1、接口测试概念 &#xff08;重点&#xff09; 接口测试是测试系统组件间接口的一种测试&#xff0c;它界于单元测试与系统测试中间。 接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。 测试的重点是要检查数据的交换&#xff0c;传递和控制管理过…

pinia 持久化插件pinia-plugin-persistedstate 安装、使用(图文详解)

序&#xff1a; 1、博主vue3、ts 5.x、pinia 2.1.3版本&#xff0c; 2、所以如果试了不行的你看看是不是自己版本和博主的对不上 3、其实就是省略掉localStorage 这一步&#xff0c;会自己写的小伙伴自己写个也是蛮快的 4、放个中文文档》Home | pinia-plugin-persistedstate 5…

【Verilog】汉明码

文章目录 汉明码定义校验位个数编码规则一个例子编码解码 C实现功能编写测试结果 Verilog实现.v功能代码testbench波形 汉明码 定义 在传输的信息流中插入验证码&#xff0c;侦测单一比特错误只能发现和修正一位错误&#xff0c;对于两位或两位以上的错误无法发现与修正 校验…

iSCSI共享存储搭建

1.简介 iSCSI&#xff1a;Internet Small Computer System Interface&#xff0c;Internet小型计算机系统接口&#xff0c;又称为IP-SAN&#xff0c;是一种基于因特网及SCSI-3协议下的存储技术。 2.iSCSI的作用 基于客户端和服务端架构的虚拟磁盘技术&#xff0c;服务端提供…

如何让url在新页面打开路由页面,并脱离vue-admin-template的壳,即不包裹在侧边栏和顶栏中

文章目录 一、打开的页面不包裹在侧边栏和顶栏中二、新窗口打开&#xff08;_blank&#xff09;三、最终效果 一、打开的页面不包裹在侧边栏和顶栏中 在使用vue-admin-template新建的页面中&#xff0c;打开的页面都是在框架内的内容区。 但假如我需要在左侧点击一个链接&…

面试题丨android面试问题合集

1、项目里静态分析和基于xposed动态工具介绍一下&#xff0c;如果不使用xposed&#xff0c;怎么实现动态分析工具&#xff1f; 静态分析工具是指在不运行程序的情况下&#xff0c;通过对程序文件进行源代码分析&#xff0c;从而对程序的安全性、可靠性、性能等进行分析的工具。…

HOOPS技术如何助力企业数字化转型?

近年来&#xff0c;随着科技的迅速发展&#xff0c;数字技术的应用已经深入到各个行业和领域。云计算、人工智能、物联网、大数据分析等技术的成熟和普及&#xff0c;为企业提供了丰富的数字化工具和解决方案。企业意识到利用这些技术可以提高效率、降低成本、创新业务模式&…