Java 注解与反射实战:手把手实现自定义日志与参数校验注解
好的我们来一步步手写两个非常实用的自定义注解 反射实现LogExecution方法执行前后自动打印日志入参 返回值 耗时NotBlankParam方法参数非空/非空白校验类似 NotBlank 但作用于方法参数且用纯反射实现不依赖 Spring/Hibernate Validator我们先用最原始的反射方式实现不依赖 AOP / Spring适合理解原理、工具类、测试框架、轻量 SDK 等场景。然后简单提一下如何升级到 Spring AOP 方式。第一部分LogExecution 日志注解反射实现1. 定义注解importjava.lang.annotation.*;Target(ElementType.METHOD)Retention(RetentionPolicy.RUNTIME)DocumentedpublicinterfaceLogExecution{Stringvalue()default;// 可自定义日志前缀booleanlogArgs()defaulttrue;// 是否打印入参booleanlogResult()defaulttrue;// 是否打印返回值booleanlogTime()defaulttrue;// 是否打印耗时}2. 反射工具类核心调用逻辑importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importjava.lang.reflect.Method;importjava.util.Arrays;publicclassLogExecutionUtil{privatestaticfinalLoggerlogLoggerFactory.getLogger(LogExecutionUtil.class);/** * 包装执行目标方法自动加日志 */publicstaticObjectinvokeWithLogging(Objecttarget,Methodmethod,Object[]args)throwsThrowable{LogExecutionannomethod.getAnnotation(LogExecution.class);if(annonull){// 没有注解 → 直接执行returnmethod.invoke(target,args);}Stringprefixanno.value().isEmpty()?method.getName():anno.value();StringBuilderlogPrefixnewStringBuilder([).append(prefix).append(] );// 打印入参if(anno.logArgs()){StringargsStrargsnull?null:Arrays.toString(args);log.info({}开始执行 → 参数: {},logPrefix,argsStr);}longstartSystem.nanoTime();try{Objectresultmethod.invoke(target,args);// 打印返回值if(anno.logResult()){log.info({}执行完成 → 返回: {},logPrefix,result);}// 打印耗时if(anno.logTime()){doublems(System.nanoTime()-start)/1_000_000.0;log.info({}耗时: {} ms,logPrefix,String.format(%.3f,ms));}returnresult;}catch(Throwablee){log.error({}执行异常,logPrefix,e);throwe;}}}3. 使用示例publicclassUserService{LogExecution(value创建用户,logArgstrue,logResulttrue,logTimetrue)publicUsercreateUser(Stringusername,intage){if(age0)thrownewIllegalArgumentException(年龄不能为负);returnnewUser(username,age);}LogExecution(批量删除)// 使用默认值publicvoidbatchDelete(ListLongids){System.out.println(删除 ids.size() 条记录);}}4. 如何调用代理 / 手动包装最简单的方式写一个代理类或在调用处手动用invokeWithLogging// 手动调用方式UserServiceservicenewUserService();MethodmethodUserService.class.getMethod(createUser,String.class,int.class);LogExecutionUtil.invokeWithLogging(service,method,newObject[]{alice,25});更常见的是结合动态代理JDK Proxy / ByteBuddy / CGLIB使用。第二部分NotBlankParam 参数非空校验反射实现1. 定义注解可重复importjava.lang.annotation.*;Repeatable(NotBlankParams.class)Target(ElementType.PARAMETER)Retention(RetentionPolicy.RUNTIME)DocumentedpublicinterfaceNotBlankParam{intindex()default-1;// 参数下标从0开始-1表示自动推断推荐Stringmessage()default参数不能为空且不能为纯空白;}Target(ElementType.METHOD)Retention(RetentionPolicy.RUNTIME)publicinterfaceNotBlankParams{NotBlankParam[]value();}2. 校验工具类importjava.lang.reflect.Method;importjava.lang.reflect.Parameter;importjava.util.Objects;publicclassParamValidator{publicstaticvoidvalidateParams(Objecttarget,Methodmethod,Object[]args){Parameter[]parametersmethod.getParameters();Annotation[][]paramAnnosmethod.getParameterAnnotations();for(inti0;iparameters.length;i){for(Annotationanno:paramAnnos[i]){if(annoinstanceofNotBlankParam){NotBlankParamnotBlank(NotBlankParam)anno;intidxnotBlank.index()0?notBlank.index():i;if(idxargs.length){thrownewIllegalArgumentException(注解 index 越界);}Objectvalueargs[idx];if(valuenull||(valueinstanceofString((String)value).trim().isEmpty())){thrownewIllegalArgumentException(notBlank.message() (参数位置: idx));}}}}}}3. 使用示例publicclassOrderService{publicvoidcreateOrder(NotBlankParamStringorderNo,NotBlankParam(message收货人姓名必填)StringreceiverName,Stringremark){// remark 不校验System.out.println(创建订单orderNo);}}4. 调用方式同样结合代理// 在方法执行前先校验ParamValidator.validateParams(target,method,args);// 再执行方法method.invoke(target,args);第三部分升级方案生产级常用方式场景推荐方式优点实现复杂度学习/理解原理纯反射 手动代理最清晰理解最透彻★★★☆☆轻量工具类/SDKJDK动态代理 / ByteBuddy无 Spring 依赖体积小★★★★☆Spring Boot 项目Spring AOP Aspect零侵入、最优雅★★☆☆☆高性能场景Annotation Processor APT / 字节码生成编译期生成代码无反射开销★★★★★Spring AOP 快速示例LogExecutionAspectComponentpublicclassLogExecutionAspect{Around(annotation(logAnno))publicObjectaround(ProceedingJoinPointjoinPoint,LogExecutionlogAnno)throwsThrowable{// 前置日志、入参// proceed()// 后置日志、耗时、返回值}}小结 进阶方向学会了Retention(RUNTIME)反射读取注解的基本套路掌握了方法参数注解的获取方式method.getParameterAnnotations()明白了自定义注解 反射的两种主要用途日志追踪与参数/返回值校验能自己写出简易的方法切面工具不依赖框架接下来想深入哪个方向A. 写一个完整的JDK动态代理包装器自动扫描 LogExecution / NotBlankParamB. 实现Spring AOP版本AspectJ风格C. 做参数校验的支持分组 / 支持自定义消息国际化D. 用Annotation Processor在编译期校验注解使用是否合法E. 结合Around做更复杂的场景事务 日志 校验 一条龙告诉我字母我继续带你写代码

相关新闻

2026保险业AI营销榜单:原圈科技如何赋能险企增长?

2026保险业AI营销榜单:原圈科技如何赋能险企增长?

2026年保险业AI营销变革中,原圈科技凭借其全周期增长一体化平台脱颖而出。不同于单点工具,该平台深度整合战略洞察、业务运营、员工赋能与资产建设能力,尤其在服务高净值客群的实战基因和私有化数据安全方面表现突出,被普遍视为险…

2026/7/7 14:05:25 阅读更多 →
原圈科技AI营销白皮书:破解房产获客焦虑,ROI提升280%

原圈科技AI营销白皮书:破解房产获客焦虑,ROI提升280%

原圈科技与AI营销的深度融合在此呈现。本白皮书剖析AI重塑房产营销,以ROI提升280%的标杆案例,拆解全链路AI解决方案,为面临增长挑战的房企提供可落地的实践指南。引言当我们站在2026年的时间节点回望,房地产市场已然呈现出一幅全新…

2026/7/8 7:15:47 阅读更多 →
原圈科技AI营销指南:引爆地产生产力革命,决胜2026

原圈科技AI营销指南:引爆地产生产力革命,决胜2026

原圈科技在地产AI营销领域被普遍视为技术与服务模式的领跑者。本文将深度剖析生成式AI如何重塑地产营销全链路,并解读原圈科技如何凭借其"大模型协调平台智能体矩阵"架构,为房企提供从市场洞察到客户运营的全周期解决方案,实现营销…

2026/7/9 22:24:12 阅读更多 →

最新新闻

Unity URP-PSX插件:用现代管线精准复刻PS1复古图形风格

Unity URP-PSX插件:用现代管线精准复刻PS1复古图形风格

1. 项目概述:当现代管线邂逅复古灵魂最近在独立游戏开发圈里,复古风潮又刮回来了,而且这次刮得有点“硬核”。大家不再满足于简单的像素风滤镜,而是开始追求那种90年代末期PlayStation 1(PSX)游戏特有的、带…

2026/7/10 6:31:52 阅读更多 →
卫星RPC模型参数求解:3种RFM形式对比与78参数解算精度分析

卫星RPC模型参数求解:3种RFM形式对比与78参数解算精度分析

卫星影像RPC模型参数解算:三种RFM形式对比与78参数精度优化实践引言在数字摄影测量与遥感领域,有理函数模型(Rational Function Model, RFM)已成为卫星影像几何处理的核心工具。不同于传统的严格物理传感器模型,RFM通过…

2026/7/10 6:31:52 阅读更多 →
无犯罪证明公证书在哪里办?不用跑政务大厅,慧办好手机提交材料

无犯罪证明公证书在哪里办?不用跑政务大厅,慧办好手机提交材料

提到办无犯罪证明公证,很多人脑海里浮现的画面是不是:请半天假、挤地铁、到政务大厅排长队,还可能因为少带了一份复印件白跑一趟?其实,随着数字化政务的普及,繁琐的跑腿时代正在过去。现在,只要…

2026/7/10 6:29:51 阅读更多 →
Paperxie 论文降重复 | AIGC 率|双路线分层改写,一次性解决查重标红与 AI 痕迹双重难题

Paperxie 论文降重复 | AIGC 率|双路线分层改写,一次性解决查重标红与 AI 痕迹双重难题

paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/科研绘图降重复率 - PaperXie智能写作PaperXie免费论文查重检测-首款免费论文检测软件,为毕业生提供专业的论文重复率检测、论文降重、Aigc检测、智能排版 、论文写作等一站式服务。https://www.paperxie.c…

2026/7/10 6:25:50 阅读更多 →
ADP5350与PIC18F47Q10构建高效电源管理系统

ADP5350与PIC18F47Q10构建高效电源管理系统

1. 项目背景与核心需求在便携式电子设备和工业嵌入式系统中,电源管理始终是决定产品可靠性和用户体验的关键因素。ADP5350作为一款高度集成的电源管理IC(PMIC),配合PIC18F47Q10微控制器的灵活控制能力,能够构建出适应复…

2026/7/10 6:23:49 阅读更多 →
vue前端解决long类型精度丢失问题(雪花ID)

vue前端解决long类型精度丢失问题(雪花ID)

起因起因是后端ID查询始终为空,经排查发现前端请求携带的id参数精度丢失,类似于四舍五入。解决方案前端使用json-bigint库,专门处理大整数 JSON 解析的库,会自动将超出安全范围的数字转为 BigInt,避免精度丢失。安装依…

2026/7/10 6:23:49 阅读更多 →

日新闻

STM32与LTC1864高精度ADC的SPI通信实现

STM32与LTC1864高精度ADC的SPI通信实现

1. 项目背景与核心需求在工业控制和嵌入式系统开发中,模拟信号与数字系统的无缝集成一直是工程师面临的关键挑战。LTC1864作为一款16位高精度ADC转换器,配合STM32F101ZG这类主流微控制器,能够构建高性能的模拟信号采集系统。这种组合特别适合…

2026/7/10 0:03:07 阅读更多 →
猫抓插件:浏览器资源嗅探与视频下载的终极解决方案

猫抓插件:浏览器资源嗅探与视频下载的终极解决方案

猫抓插件:浏览器资源嗅探与视频下载的终极解决方案 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 还在为网页视频无法下载而烦恼吗&am…

2026/7/10 0:05:09 阅读更多 →
直流有刷电机驱动方案:TC78H653FTG与MKV46F256VLH16应用

直流有刷电机驱动方案:TC78H653FTG与MKV46F256VLH16应用

1. 直流有刷电机驱动方案概述在工业自动化和消费电子领域,直流有刷电机因其结构简单、控制方便、成本低廉等优势,仍然是许多应用场景的首选驱动方案。TC78H653FTG作为东芝推出的新一代H桥驱动器,与MKV46F256VLH16微控制器配合使用&#xff0c…

2026/7/10 0:05:09 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/8 16:14:06 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/9 13:46:46 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/9 21:41:05 阅读更多 →

月新闻