Java 自定义注解

Java 自定义注解, 以及@interface @Target @Retention @Around @Before @After ProceedingJoinPoint JoinPoint 等用法

注解应用非常广泛,我们自定义注解能简化开发各种各种业务

一、关键字解释
(1) 定义注解时,关键字
@interface 来表示注解类的类型
在这里插入图片描述
@Target @Retention 这两个具体值,需要分析注解的应用场景来确定;
对于“调用方法时打印入参和出参”的例子,是在调用调用方法时,则使用RetentionPolicy.RUNTIME, 且作用于方法上,则使用ElementType.METHOD;

(2) 实现注解时,关键字
在这里插入图片描述

@Before、@After、@AfterReturning 方法的入参是JoinPoint类型
@Around 方法的入参是ProceedingJoinPoint类型

ProceedingJoinPoint继承了JoinPoint类型,并扩展出了proceed()方法,执行proceed()也就是执行原始的函数具体业务方法,可以通过JoinPoint对象获取一些请求上的参数,比如request,parms等;

执行顺序:
@Around >> @Before >> 被添加注解的方法业务执行 >> @After >> @AfterReturning

特别注意:
注解中,可以存在@Around、@Before 、@After或、@AfterReturning任意组合
注解中,存在@Around ,也存在@Before 、@After或、@AfterReturning时、会先执行@Around;

在@Around中,执行参数的ProceedingJoinPoint.proceed(), 会触发@Before 、“被添加注解的方法业务执行” 、@After、@AfterReturning的执行,

在@Around中,不执行参数的ProceedingJoinPoint.proceed(), 不会触发@Before 、“被添加注解的方法业务执行”,特别注意;所以正常逻辑中,ProceedingJoinPoint.proceed()都应该触发执行。

@Around 的返回值应该为 “被添加注解的方法业务执行” 的返回值。通过获取Object bizData = ProceedingJoinPoint.proceed(), 也可以对返回值加工再返回;

三、代码实现
(1) 定义注解

package com.xxxxx.annotation;import java.lang.annotation.*;@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MethodParam {/*** 自定义方法, 日志描述信息, 可有可无** @return*/String description() default "";/*** 自定义方法1, 日志描述信息, 可有可无** @return*/String description1() default "";/*** 自定义方法2, 日志描述信息, 可有可无** @return*/String description2() default "";
}

其中description() description1() description2() 都是自定义方法(相当于调用注解时的传参),当业务需要就声明,不需要就无需声明

(2) 实现注解

package com.xxxxx.annotation.annotationAspect;import com.xxxxx.annotation.MethodParam;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;import java.lang.reflect.Method;@Aspect
@Component
public class MethodParamAspect {/*** 声明切点*/@Pointcut(value = "@annotation(com.xxxxx.annotation.MethodParam)")public void doPointCut() {System.out.print("执行doPointCut \n");}/*** 调用方法前后执行* @param joinPoint*/@Around(value = "doPointCut()")public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable{System.out.print("执行doAround \n");//获取注解入参MethodSignature signature = (MethodSignature) joinPoint.getSignature();Method method = signature.getMethod();MethodParam methodParamNew = method.getAnnotation(MethodParam.class);String description = methodParamNew.description();String description1 = methodParamNew.description1();String description2 = methodParamNew.description2();//被添加注解的方法业务执行Object bizData = joinPoint.proceed();//处理其他业务return bizData;}/*** 调用方法之【前】执行* @param joinPoint*/@Before(value = "doPointCut()")public void doBefore(JoinPoint joinPoint){System.out.print("执行doBefore \n");//处理其他业务}/**** 调用方法之【后】执行** @param joinPoint*/@After(value = "doPointCut()")public void doAfter(JoinPoint joinPoint){System.out.print("执行doAfter \n");//处理其他业务}/**** @After执行之【后】执行** @param joinPoint* @param res 具体业务的返回值 (可有可无)*/@AfterReturning(value = "doPointCut()",returning = "res")public void doAfterReturning(JoinPoint joinPoint, String res){System.out.print("执行doAfterReturning \n");//处理其他业务}
}

(3) 使用注解

package com.xxxxx.component;import com.xxxxx.annotation.MethodParam;
import org.springframework.stereotype.Component;
import java.util.Random;@Component
public class OrderComponent {@MethodParam(description = "aaa", description1 = "bbb", description2 = "ccc")public String testAnnotation(String val1, String val2){String aa = val1.concat(val2).concat(String.valueOf(String.format("%04d",new Random().nextInt(9999))));System.out.print(aa + "\n");return aa;}
}

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

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

相关文章

Spring Boot学习随笔- 实现AOP(JoinPoint、ProceedingJoinPoint、自定义注解类实现切面)

学习视频:【编程不良人】2021年SpringBoot最新最全教程 第十一章、AOP 11.1 为什么要使用AOP 问题 现有业务层开发存在问题 额外功能代码存在大量冗余每个方法都需要书写一遍额外功能代码不利于项目维护 Spring中的AOP AOP:Aspect 切面 Oriented 面向…

前端面试题(计算机网络):常见的HTTP请求头和响应头

前端面试题(计算机网络):常见的HTTP请求头和响应头 HTTP Request Header 常见的请求头:HTTP Responses Header 常见的响应头:常见的 Content-Type 属性值有以下四种: HTTP Request Header 常见的请求头&…

竞赛保研 python 机器视觉 车牌识别 - opencv 深度学习 机器学习

1 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 基于python 机器视觉 的车牌识别系统 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分工作量:3分创新点:3分 🧿 更多资…

【Python 基础】-- 在 mac OS 中安装 多个 python 版本

目录 1、需求 2、实现 2.1 安装 pyenv 2.2 安装 pyenv-virtualenv 2.3 配置环境变量 2.4 创建 python 3.9.9 的环境 2.5 激活环境,在当前项目目录中使用,即执行 python 1、需求 由于项目所依赖的 python 版本有多个,需要在不同的 pyth…

主从reactor多线程实现

现场模型图片,从网上找的 出于学习的目的实现的,如有不对的地方欢迎留言知道,简单实现了http的请求,可通过postman进行访问 启动项目: 返回数据示例 postman请求 附上源码,有问题直接看源码吧

智能优化算法应用:基于闪电连接过程算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于闪电连接过程算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于闪电连接过程算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.闪电连接过程算法4.实验参数设定…

Flink实时电商数仓(二)

GitLab的用户创建和推送 在root用户-密码界面重新设置密码添加Leader用户和自己使用的用户使用root用户创建相应的群组使用Leader用户创建对应的项目设置分支配置为“初始推送后完全保护”设置.gitignore文件,项目配置文件等其他非通用代码无需提交安装gitlab proj…

(JAVA)-创建多线程的方式

1.继承Thread类 1.创建一个继承字Thread类的子类 2.重写Thread类的run方法 public class MyThread extends Thread{Overridepublic void run() {for (int i 0; i < 100; i) {System.out.println(getName()"hello");}} }3.创建Thread类的子类对象 4.通过子类对象调…

Ubuntu:那些年踩过的坑?注意事项分享

Ubuntu系统在使用过程中可能会遇到一些需要注意的"坑"&#xff0c;以下是一些常见的问题和示例&#xff1a; 1.权限问题&#xff1a; 在Ubuntu中&#xff0c;默认情况下&#xff0c;许多系统文件和目录只有root用户才能修改。如果你试图以普通用户身份修改这些文件&a…

HarmonyOS应用开发实战—开箱即用的应用首页页面【ArkTS】【鸿蒙专栏-34】

一.HarmonyOS应用开发实战—开箱即用的应用首页页面【ArkTS】【鸿蒙专栏-34】 1.1 项目背景 HarmonyOS(鸿蒙操作系统)是华为公司推出的一种分布式操作系统。它被设计为一种全场景、全连接的操作系统,旨在实现在各种设备之间的无缝协同和共享,包括智能手机、平板电脑、智能…

轻量级购物小程序H5产品设计经典样例

主要是看到这个产品设计的不错值得借鉴特记录如下&#xff1a; 不过大多数购物app都大致相同&#xff0c;这个算是经典样例&#xff0c;几乎都可以复制&#xff0c;我第一次使用&#xff0c;感觉和顺畅。看上去产品是经过打磨的&#xff0c;布局非常好。内容也很丰富。支持异业…

Leetcode—128.最长连续序列【中等】

2023每日刷题&#xff08;六十四&#xff09; Leetcode—128.最长连续序列 实现代码 class Solution { public:int longestConsecutive(vector<int>& nums) {unordered_set<int> s;for(auto num: nums) {s.insert(num);}int longestNum 0;for(auto num: s) …

LeetCode day27

LeetCode day27 —今天做到树&#xff0c;&#xff0c;&#xff0c;对不起我的数据结构老师啊~~~ 7. 整数反转 给你一个 32 位的有符号整数 x &#xff0c;返回将 x 中的数字部分反转后的结果。 如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] &#xff0c…

Maven scope属性解读和使用注意事项

目录 compile runtime test system provided import dependencyManagement标签介绍 maven的scope有哪些&#xff1a; maven的scope一共包括&#xff1a;compile、runtime、test、system、provided、import。 compile <dependency><groupId>org.apache.htt…

【PostgreSQL】从零开始:(十六)数据类型-数值类型

数值类型定义 数值类型是一种用于存储数字的数据类型。在编程语言中&#xff0c;数值类型通常包括整数类型和浮点数类型。 整数类型用于存储整数值&#xff0c;包括正整数、负整数和零。在不同的编程语言中&#xff0c;整数类型可能有不同的大小限制&#xff0c;例如8位、16位…

【AI图集】猫狗的自动化合成图集

猫是一种哺乳动物&#xff0c;通常被人们作为宠物饲养。它们有柔软的毛发&#xff0c;灵活的身体和尖锐的爪子。猫是肉食性动物&#xff0c;主要以肉类为食&#xff0c;但也可以吃一些蔬菜和水果。猫通常在夜间活动&#xff0c;因此它们需要足够的玩具和活动空间来保持健康和快…

k8s pod常用资源清单

K8S 的资源清单 参数名类型字段说明apiVersionStringK8S APl 的版本&#xff0c;可以用 kubectl api versions 命令查询kindStringyam 文件定义的资源类型和角色metadataObject元数据对象&#xff0c;下面是它的属性metadata.nameString元数据对象的名字&#xff0c;比如 pod …

Android Uri scheme协议file转content

一、Uri的介绍 在Android开发中&#xff0c;Uri&#xff08;Uniform Resource Identifier&#xff09;是用于标识和访问各种资源的核心概念。这些资源可能包括文件、网络URL、数据库记录等。在处理这些资源时&#xff0c;我们可能会遇到不同的Uri协议&#xff0c;如file和conte…

[PTA]矩阵列平移

给定一个 nn 的整数矩阵。对任一给定的正整数 k<n&#xff0c;我们将矩阵的偶数列的元素整体向下依次平移 1、……、k、1、……、k、…… 个位置&#xff0c;平移空出的位置用整数 x 补。你需要计算出结果矩阵的每一行元素的和。 输入格式&#xff1a; 输入第一行给出 3 个…

Another git process seems to be running in this repository, e.g. an editor o

操作任何git命令&#xff0c;都提示该内容。 Another git process semms to be running in this repository, e.g. an editor opened by ‘git commit’. Please make sure all processes are terminated then try again. If it still fails, a git process remove the file m…