用注解实现方法开关

news2024/11/27 10:26:48

一、自定义注解的基本使用

java.lang.annotation 提供了四种元注解,专门注解其他的注解(在自定义注解的时候,需要使用到元注解):
@Documented – 注解是否将包含在JavaDoc中
@Retention – 什么时候使用该注解
@Target – 注解用于什么地方
@Inherited – 是否允许子类继承该注解

1.)@Retention – 定义该注解的生命周期
● RetentionPolicy.SOURCE : 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
● RetentionPolicy.CLASS : 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式
● RetentionPolicy.RUNTIME : 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。

2.)Target – 表示该注解用于什么地方。默认值为任何元素,表示该注解用于什么地方。可用的ElementType 参数包括
● ElementType.CONSTRUCTOR: 用于描述构造器
● ElementType.FIELD: 成员变量、对象、属性(包括enum实例)
● ElementType.LOCAL_VARIABLE: 用于描述局部变量
● ElementType.METHOD: 用于描述方法
● ElementType.PACKAGE: 用于描述包
● ElementType.PARAMETER: 用于描述参数
● ElementType.TYPE: 用于描述类、接口(包括注解类型) 或enum声明

3.)@Documented – 一个简单的Annotations 标记注解,表示是否将注解信息添加在java 文档中。

4.)@Inherited – 定义该注释和子类的关系
@Inherited 元注解是一个标记注解,@Inherited 阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited 修饰的annotation 类型被用于一个class,则这个annotation 将被用于该class 的子类。

编写规则

  1. Annotation 型定义为@interface, 所有的Annotation 会自动继承java.lang.Annotation这一接口,并且不能再去继承别的类或是接口.
  2. 参数成员只能用public 或默认(default) 这两个访问权修饰
  3. 参数成员只能用基本类型byte、short、char、int、long、float、double、boolean八种基本数据类型和String、Enum、Class、annotations等数据类型,以及这一些类型的数组.
  4. 要获取类方法和字段的注解信息,必须通过Java的反射技术来获取 Annotation 对象,因为你除此之外没有别的获取注解对象的方法
  5. 注解也可以没有定义成员,,不过这样注解就没啥用了
    PS:自定义注解需要使用到元注解

示例

在这里插入图片描述

AOP

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

使用

在这里插入图片描述

执行结果

在这里插入图片描述

二、编写实例

定义一个注解类接口

添加四个元注解
定义属性-返回类型类Class<?>、返回类型是否可为空boolean-可以赋默认值default false

定义一个切面

添加注解@Aspect @Component
定义一个切面方法,返回值为void,添加注解@Pointcut("@annotation(注解接口的全类名路径)"),
定义一个环绕方法,参数为ProceedingJoinPoint,注解接口类,添加@Around(切面方法() && @annotation(参数注解接口类的自定义名称)),内部实现:获得切点的方法名和类名,通过注入的配置类获取配置的值,如果为Y则return point.proceed(),表示进入方法的执行,如果注解接口类的boolean属性为true,则返回null,获取注解接口类的返回类型类,return clazz.newInstance;

定义一个配置类

添加注解@Component @RefreshScope @Data
定义私有属性 类名 方 法 名 , 添 加 添 加 注 解 @ V a l u e ( " 方法名,添加添加注解@Value(" @Value("{类名.方法名}")
提供一个get方法,参数为类名和方法名
return 配置工具类.getValueByKeyAndObj(className,methodName,this)

定义一个配置工具类

提供一个静态的getValueByKeyAndObj方法,参数为(String key,String value,Object objc)

String str = key + "$" + value;
Fields[] declaredFields = objc.getClass().getDeclaredFields();
for (Field declaredField: declaredFields) {
boolean equals = str. equals (declaredField. getName ());
if (equals)
try {
declaredField.setAccessible(true);
return declaredField.get (obje);
} catch (IllegalAccessException e) {
return null;

使用注解

@JudgeCallable(resultClass = ArrayList.class, isNull = false)

注意只能用到control类以及impl实现类上,不能用于接口上
其中resultClass只能用List的实现类ArrayList,不能使用接口类

思考:为什么自定义的注解不能用于接口上?

前置知识点:注解的继承问题
“对于接口,在接口中的注解无论如何都不能被继承,不论是子接口继承父接口的情况还是接口的实现类的情况,不论是对接口上还是接口中的方法上的注解,都不能被继承。

一个类用上了 @Inherited 修饰的注解,那么其子类也会继承这个注解,与方法上的注解的继承性无关

总结:
接口用上个 @Inherited 修饰的注解,其实现类不会继承这个注解
父类的方法用了 @Inherited 修饰的注解,子类也不会继承这个注解

为什么自定义的注解不能用于接口上?
因为我们使用了AOP特性,即Spring动态代理,Spring 的动态代理主要分为两种,一种是JDK 动态代理 ;一种是CGLIB 动态代理

  • JDK 动态代理主要是针对实现了某个接口的类。该方式基于反射的机制实现,会生成一个实现相同接口的代理类,然后通过对方法的重写,实现对代码的增强。
    在该方式中接口中的注解无法被实现类继承,AOP 中的切点无法匹配上实现类,所以也就不会为实现类创建代理,所以我们使用的类其实是未被代理的原始类,自然也就不会被增强了。
  • 使用 CGLIB 动态代理
    在不存在切点注解继承的情况(在类上注解,子类可继承),AOP 可进行有效拦截(CGLIB动态代理)。但是还要考虑以下存在注解继承的情况:
    有父类 Parent,和子类 Sub ,切点注解在父类方法。则根据上边提到的只有方法的重写问题,可知,被重写的方法(不继承父类的注解)将不会被拦截,而未重写的方法(继承父类的注解)则走 Parent 路线,可以被 AOP 感知拦截。

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

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

相关文章

【算法】动态规划-斐波那契模型

文章目录 结论斐波那契模型第 N 个泰波那契数三步问题使用最小花费爬楼梯**方法1&#xff1a;**以i位置为结尾....方法2&#xff1a;以i位置为起点.... 解码方法 结论 对于线性dp&#xff0c;一般是用经验题目要求来定义状态表示&#xff1a; 以某个位置为结尾…以某个位置为…

React 通过一个输入内容加入列表案例熟悉 Hook 基本使用

我们创建一个react项目 在src下创建components文件夹 在下面创建一个index.jsx index.jsx 参考代码如下 import React, { useState } from "react";const useInputValue (initialValue) > {const [value,setValue] useState(initialValue);return {value,onCha…

【2023,学点儿新Java-01】从查看本机 jdk版本 开始 | Java基础全程脉络图、Java工程师全程技术路线、Java职业晋升路线图

一个人把生命耗尽&#xff0c;应该是为了一些美好的东西&#xff0c;值得的东西&#xff0c;用蓬勃如烈火的生命力 去战胜一个又一个人生的悲剧&#xff0c;这本身就是人生的意义之一吧&#xff01; &#x1f3af;作者主页&#xff1a; 追光者♂&#x1f525; &#x1f338;个人…

Win10 系统专业版远程桌面如何才能多用户同时登录使用?

环境&#xff1a; Win10专业版19041 RDPWrap-v1.6.2 dell5493笔记本 问题描述&#xff1a; Win10 系统专业版远程桌面如何才能多用户同时登录使用&#xff1f; 解决方案&#xff1a; 安装RDPWrap 1.关闭remote desktop services服务 安装RDP之前&#xff0c;要先关闭re…

8年性能测试工程师告诉你,压力测试详解,如何做压力测试...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 什么是压力测试&a…

灯塔工厂PLC智慧边缘计算机嵌入式linux系统

随着工业物联网的发展&#xff0c;越来越多的企业开始将工业自动化设备接入到物联网平台&#xff0c;以实现设备远程监控、运维和管理。其中&#xff0c;PLC智能网关作为连接PLC和物联网平台的重要设备&#xff0c;发挥着至关重要的作用。本文将介绍PLC数据采集控制网关的功能和…

文心一言 VS 讯飞星火 VS chatgpt (42)-- 算法导论5.4 6题

六、假设将n个球投人 n 个箱子里&#xff0c;其中每次投球独立&#xff0c;并且每个球等可能落入任何箱子。空箱子的数目期望是多少?正好有一个球的箱子的数目期望是多少? 文心一言&#xff1a; 这是一个典型的概率问题。首先&#xff0c;我们可以通过简单的计算来理解问题…

【论文】YOLOv7运行train.py和test.py时,打印不出来计算量GFLOPs解决方法

目录 前提案例解决步骤运行方式打印效果 前提 我在AutoDL云服务器上&#xff0c;会运行失败&#xff0c;不晓得为啥&#xff0c;我感觉可能是CUDA版本的问题&#xff0c;CUDA版本低了就会没有那么深的计算量吧 AutoDL上&#xff08;显卡RTX3090&#xff0c;4GB&#xff09;安…

java的网络编程

一、网络编程的三要素 IP、端口号、协议。 特殊IP地址127.0.0.1&#xff0c;也可以是localhost&#xff0c;是回送地址也称回环地址&#xff0c;也称本机IP&#xff0c;永远只会寻找当前所在本机。 常见cmd命令&#xff1a; ipconfig:查看本机IP地址&#xff1b; ping:检查网络…

Innovus: dbGet 快速学习教程

dbGet是innovus/encounter工具自带的"database access command"命令中的一部分&#xff0c;它几乎可以用来获取设计相关的一切信息。 输入dbGet 按[Tab]键&#xff0c;能看到三个选项&#xff0c;分别是head / top /selected。这三个选项所代表的意义如下: head --…

ubuntu 22.04安装mysql 8.0与避坑指南

MySQL 是一个开源数据库管理系统&#xff0c;可作为流行的 LAMP&#xff08;Linux、Apache、MySQL、PHP/Python/Perl&#xff09;堆栈的一部分安装。 它实现了关系模型并使用结构化查询语言&#xff08; SQL&#xff09;来管理其数据。 本教程将介绍如何在 Ubuntu 22.04 服务器…

appium+python在Android端的环境配置

一、安装配置JDK 一、安装环境 1、本机系统&#xff1a;Windows 10&#xff08;64位&#xff09; 2、JDK版本&#xff1a;1.8&#xff08;64位&#xff09; 二、下载安装 1、JDK和JRE简介 Java环境分JDK和JRE &#xff0c;JDK就是Java Development Kit。简单的说JDK是面向…

JMeter安装图文及入门教程,(附视频教程)

目录 一、JMeter介绍 二、下载配置安装 三、JMeter入门压测实例 总结&#xff1a; 一、JMeter介绍 JMeter是Apache组织开发的基于Java的压力测试工具。用于对软件做压力测试&#xff0c;它最初被设计用于Web应用测试&#xff0c;但后来扩展到其他测试领域。它可以用于测试静…

Go语言并发之context标准库

1、Go语言并发之context标准库 Go中的 goroutine 之间没有父与子的关系&#xff0c;也就没有所谓子进程退出后的通知机制&#xff0c;多个 goroutine 都是平行地 被调度&#xff0c;多个 goroutine 如何协作工作涉及通信、同步、通知和退出四个方面。 通信&#xff1a;chan 通…

ResNet

论文信息 论文名称&#xff1a;Deep Residual Learning for Image Recognition 论文地址&#xff1a;https://arxiv.org/pdf/1512.03385.pdf 发表期刊&#xff1a;CVPR 发表年份&#xff1a;2016 主要问题 在引言中作者提出了一个问题&#xff1a;训练一个更好的网络是否像堆…

这个网站,多希望你早点知道,越早越好!

这是一个有趣、神奇的个人博客网站。 这是一个马斯克经常上的网站&#xff0c;而且马斯克还在推特上关注了这个网站的账号。 网站地址&#xff1a;https://waitbutwhy.com/ 这个网站上的内容并不多&#xff0c;网站2013年创建的&#xff0c;至今已有10年&#xff0c;一共才产出…

python爬虫工程师,如何从零开始部署Scrapyd+Feapder+Gerapy?

突然被告知要连着上整整十一天的班&#xff0c;有一点点累&#xff0c;简单更新一下内容吧&#xff0c;水个积分 关注公众号&#xff1a;python技术训练营&#xff0c;精选优质文档&#xff0c;好玩的项目 内容&#xff1a; 1.面试专题几十个大厂面试题 2.入门基础教程 3.11模块…

活动邀请函五秒钟下载即用

在日常中&#xff0c;人们都是以纸质的邀请函发送给被邀请者&#xff0c;不仅需要花费大量的精力和时间去书写发送活动邀请函&#xff0c;还存在着被邀请人没有及时收到活动邀请函而错过参与的时间等。而这样只需制作一份就可以全网分享&#xff0c;用户短时间就能收到活动邀请…

可变参数列表

"多少人都&#xff0c;生来纯洁完美&#xff0c;心底从不染漆黑。" 我们想要实现一个函数&#xff0c;这个函数的功能是返回一个整形的最大值。 emm&#xff0c;似乎有那点味道。但这应用场景似乎很受限制&#xff0c;因为这个函数比较的有效区间&#xff0c;只能装下…

Pycharm远程开发之全局pip,激活远程虚拟环境pip,以及pip的--user选项

前言 最近需要部署一下生成对抗网络的开发环境&#xff0c;我自己的笔记本没有带显卡&#xff0c;想到实验室的服务器有带显卡索性就用实验室服务器的环境开发&#xff0c;通过pycharm的远程开发功能连接到服务器&#xff0c;本来以为轻轻松松就可以开始写代码了&#xff0c;结…