Java注解的入门学习

一、概念

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 "查询";
    }
}

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

 控制台返回 

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

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

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

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

本周大新闻|Vision Pro头显重磅发布;苹果收购AR厂商Mira

本周XR大新闻&#xff0c;上周Quest 3发布之后&#xff0c;本周苹果MR头显Vision Pro正式发布&#xff0c;也是本周AR/VR新闻的重头戏。 ​AR方面&#xff0c;苹果发布VST头显Vision Pro&#xff08;虽然本质是台VR&#xff0c;但以AR场景为核心&#xff09;以及visionOS&…

【三、网络配置与系统管理】

1 网络配置 ifconfig 显示网络接口的配置信息 [rootredis100 ~]# ifconfig ens33: flags4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.10.100 netmask 255.255.255.0 broadcast 192.168.10.255inet6 fe80::f5c3:6a96:fe05:1965 prefixlen 64 scop…

如何使用Docker实现分布式Web自动化!

1、前言 顺着docker的发展&#xff0c;很多测试的同学也已经在测试工作上使用docker作为环境基础去进行一些自动化测试&#xff0c;这篇文章主要讲述在docker中使用浏览器进行自动化测试如果可以实现可视化&#xff0c;同时可以对浏览器进行相关的操作。 如果你想学习自动化测…

畅聊趣坊项目测试报告

文章目录 项目背景项目功能测试计划与设计功能测试自动化测试 测试结果功能测试结果UI自动化测试结果 项目背景 在浏览网站时&#xff0c;发现好多网站开放出聊天的窗口&#xff0c;我们一发送消息就会收到一条消息&#xff0c;好奇这个功能是怎么实现的&#xff0c;最后查阅资…

cmake 基本使用

目录 CMake都有什么? 使用cmake一般流程为&#xff1a; 1 生成构建系统 使用命令在build外编译代码: cmake基本语法 指定使用最低版本的cmake 指定项目名称 指定生成目标文件的名称 指定C版本 cmake配置文件使用 cmake配置文件生成头文件 版本号定义方法一: 版本号定…

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

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

C++中string类的常用函数

文章目录 默认成员函数常见构造函数(constructor) string类的容量操作size()empty()capacity()reserve()clear()resize() string类对象的访问及遍历操作重载 [ ]begin()end()begin() end() 遍历字符串rbegin()rend()rbegin() rend()反向遍历字符串C11范围for string类对象修改…

广域网技术——ppp,pppoe

目录 PPP协议概述 PPP协议原理 PPP协议三大组件&#xff1a; PPP链路建立流程 PPP连接建立接口状态&#xff1a; LCP协议报文格式 PPP协议报文格式&#xff1a; 1&#xff0c;链路层建立连接过程 LCP协商过程-正常协商 LCP协商-参数不一致 LCP协商-参数不识别 2&#xf…

YOLOv5/v7 添加注意力机制,30多种模块分析③,GCN模块,DAN模块

目录 一、注意力机制介绍1、什么是注意力机制&#xff1f;2、注意力机制的分类3、注意力机制的核心 二、GCN 模块1、GCN 模块的原理2、实验结果3、应用示例 三、DAN模块1、DAN模块的原理2、实验结果3、应用示例 大家好&#xff0c;我是哪吒。 &#x1f3c6;本文收录于&#xf…

AMC12和高考数学哪个更难?知识点有哪些不同?

AMC12和高考数学哪个更难&#xff1f;知识点有哪些不同&#xff1f;今天小编给大家来详细介绍一下&#xff01; 难度对比 从难度上看&#xff0c;高考数学的计算量更大&#xff0c;并且知识点比AMC10/12超前&#xff0c;需要用到极限和微积分的知识。 反观AMC10/12不需要用到…

数据结构与算法之美 | 栈

栈结构&#xff1a;后进者先出&#xff0c;先进者后出 栈是一种“操作受限”的线性表 当某个数据集合只涉及在一端插入和删除数据&#xff0c;并且满足后进先出、先进后出的特性&#xff0c;这时我们就应该首选“栈”这种数据结构 栈的实现 使用数组实现&#xff1a;顺序栈…

初探图神经网络——GNN

title: 图神经网络(GNN) date: tags: 随笔知识点 categories:[学习笔记] 初探图神经网络(GNN) 文章来源&#xff1a;https://distill.pub/2021/gnn-intro/ 前言&#xff1a;说一下为什么要写这篇文章&#xff0c;因为自己最近一直听说“图神经网络”&#xff0c;但是一直不了…

pycharm使用之torch_sparse安装

正式安装之前要先查看一下torch的版本 一、查看torch版本 1、winR &#xff0c;输入cmd 2、输入python 3、 输入import torch&#xff0c;然后输入torch.__version__&#xff0c;最后回车 可以看到我的torch版本是1.10.0 二、下载合适的torch_sparse版本 1、打开链接 https…

接口反应慢优化

遇到某个功能&#xff0c;页面转圈好久&#xff0c;需要优化 1.F12 查看接口时间 2.看参数 总共耗时9.6s Waiting for sercer response 时间是2秒 Content Download 7秒 慢在Content Download F12查看接口响应 显示Failed to load response data:Request content was e…

spark入门 高可用部署HA(五)

一、standalone基于修改部署 https://blog.csdn.net/weixin_43205308/article/details/131070277?spm1001.2014.3001.5501 二、安装ZOOKEEPER zookeeper 安装下载与集群 三、修改conf下的spark-env.sh vim conf/spark-env.sh注释以下内容&#xff08;根据自己环境修改&am…

visual studio 2022,ADO.NET 实体数据模型添加 sqlite数据库对象

文章目录 前言前期环境博客github 文档解析文件安装说明文件下载省流版nuget环境配置成功标志sqlite连接测试 前言 我们知道ADO.NET 实体数据模型特别适合动态开发数据库。因为ADO.NET可以使用DB First 开发 我们在开发一个程序的时候&#xff0c;经常会动态更新数据库字段&a…

算法模板(3):搜索(4):高等图论

高等图论 有向图的强连通分量 相关概念 强连通分量&#xff1a;Strongly Connected Component (SCC).对于一个有向图顶点的子集 S S S&#xff0c;如果在 S S S 内任取两个顶点 u u u 和 v v v&#xff0c;都能找到一条 u u u 到 v v v 的路径&#xff0c;那么称 S S…

C++多态和文件读写

C黑马&#xff0c;每天1.5倍速2个视频&#xff08;1小时&#xff09;&#xff0c;看到9月1日完成314个视频 目录 &#x1f511;多态 &#x1f333;基本语法 &#x1f333;原理剖析 &#x1f333;案例1 -- 计算器类 &#x1f333;纯虚函数和抽象类 &#x1f333;案例2 --…

redis知识复习

redis知识复习 redis基础知识一. redis的认识1. 非关系型数据库 与 传统数据库 的区别2. 安装redis并设置自启动3. 熟悉命令行客户端4. 熟悉图形化工具RDM 二. redis的命令与数据结构1. 数据结构介绍2. redis通用命令&#xff08;熟练掌握&#xff09; 三. redis的Java客户端1.…

SpringBoot整合Flyway实现数据库的初始化和版本管理

文章目录 一、Flyway1、介绍2、业务痛点3、个人理解 二、SpringBoot整合flyway1、整合2、SQL文件命名3、版本号校验算法4、工作流程5、注意事项 一、Flyway 1、介绍 Flyway 是一款开源的数据库版本管理工具。它可以很方便的在命令行中使用&#xff0c;或者在Java应用程序中引入…