当前位置: 首页 > article >正文

JAVA重点基础、进阶知识及易错点总结(35)注解与反射

Java 巩固进阶 · 第 35 天主题注解与反射结合 —— 让注解活起来 进度概览继昨天学习注解定义之后今天进入注解的核心应用场景注解 反射。单独的注解只是标签只有结合反射读取并处理才能产生实际逻辑。这是 Spring、MyBatis、JUnit 等框架的底层核心。 核心价值框架原理理解 SpringAutowired注入、MyBatisSelect映射、SpringMVCRequestMapping绑定的底层实现。动态逻辑运行时根据注解信息动态执行代码实现配置即代码。工具开发掌握自定义校验框架、简易 IOC 容器、自动化日志切面的实现思路。面试高频反射读取注解流程、注解处理器APT概念是高级开发常考题。一、核心原理反射读取注解信息 1. 反射获取注解的 APIClass?clazzMyClass.class;// ✅ 1. 判断是否有指定注解if(clazz.isAnnotationPresent(MyAnnotation.class)){// 有注解}// ✅ 2. 获取注解实例读取属性值MyAnnotationannclazz.getAnnotation(MyAnnotation.class);Stringvalueann.value();// 读取注解属性// ✅ 3. 获取所有注解Annotation[]allAnnsclazz.getAnnotations();// ✅ 4. 获取方法/字段上的注解Methodmethodclazz.getMethod(doSomething);LoglogAnnmethod.getAnnotation(Log.class);⚠️关键前提注解必须用Retention(RetentionPolicy.RUNTIME)修饰否则运行时反射读取不到2. 处理流程图解定义注解 (Log) ↓ 标注在代码上 (UserService.createUser) ↓ 反射扫描类 (Class.forName) ↓ 获取方法 (getDeclaredMethods) ↓ 检查注解 (isAnnotationPresent) ↓ 读取属性 (getAnnotation) ↓ 执行逻辑 (打印日志/校验/注入)二、实战场景 1简易参数校验框架 ✅1. 定义校验注解// ✅ 定义 NotNull 注解Target(ElementType.FIELD)Retention(RetentionPolicy.RUNTIME)publicinterfaceNotNull{Stringmessage()default字段不能为空;}// ✅ 定义 Range 注解Target(ElementType.FIELD)Retention(RetentionPolicy.RUNTIME)publicinterfaceRange{intmin()default0;intmax()default100;}2. 标注在实体类上publicclassUser{NotNull(message用户名不能为空)privateStringname;Range(min1,max150)privateintage;// getter/setter}3. 实现校验器核心逻辑publicclassValidator{publicstaticvoidvalidate(Objectobj)throwsException{Class?clazzobj.getClass();// 1. 获取所有字段for(Fieldfield:clazz.getDeclaredFields()){field.setAccessible(true);Objectvaluefield.get(obj);// 2. 检查 NotNullif(field.isAnnotationPresent(NotNull.class)){NotNullannfield.getAnnotation(NotNull.class);if(valuenull||.equals(value)){thrownewIllegalArgumentException(ann.message());}}// 3. 检查 Rangeif(field.isAnnotationPresent(Range.class)){Rangeannfield.getAnnotation(Range.class);if(valueinstanceofInteger){intval(Integer)value;if(valann.min()||valann.max()){thrownewIllegalArgumentException(field.getName() 超出范围ann.min()-ann.max());}}}}}}// 测试UserusernewUser();user.setName();// 故意留空Validator.validate(user);// 抛异常用户名不能为空框架关联这就是Hibernate Validator (JSR-303)和 SpringValid的底层原理三、实战场景 2简易 AOP 日志切面 1. 回顾 Log 注解第 34 天定义Target(ElementType.METHOD)Retention(RetentionPolicy.RUNTIME)publicinterfaceLog{Stringvalue()default;Stringlevel()defaultINFO;}2. 实现日志拦截器模拟 Spring AOPpublicclassLogInterceptor{// ✅ 核心方法处理带有 Log 注解的方法publicstaticvoidinvokeWithLog(Objecttarget,Methodmethod,Object[]args)throwsException{// 1. 检查方法是否有 Log 注解if(method.isAnnotationPresent(Log.class)){LoglogAnnmethod.getAnnotation(Log.class);// 2. 前置日志System.out.println(【日志】开始执行logAnn.value() 级别logAnn.level());longstartSystem.currentTimeMillis();// 3. 执行目标方法method.setAccessible(true);Objectresultmethod.invoke(target,args);// 4. 后置日志longcostSystem.currentTimeMillis()-start;System.out.println(【日志】执行完成耗时costms);return;}// 无注解直接执行method.setAccessible(true);method.invoke(target,args);}}// 测试UserServiceservicenewUserService();Methodmethodservice.getClass().getMethod(createUser,String.class);LogInterceptor.invokeWithLog(service,method,newObject[]{Alice});框架关联Spring AOP 的Aspect本质也是扫描注解 动态代理 反射调用。四、实战场景 3简易依赖注入IOC 雏形1. 定义 MyAutowired 注解Target(ElementType.FIELD)Retention(RetentionPolicy.RUNTIME)publicinterfaceMyAutowired{Stringvalue()default;// 指定 Bean 名称}2. 实现简易容器publicclassSimpleContainer{privatestaticMapString,ObjectbeansnewHashMap();// ✅ 注册 BeanpublicstaticvoidregisterBean(Objectbean){Stringnamebean.getClass().getSimpleName();beans.put(name,bean);}// ✅ 注入依赖publicstaticvoidinjectDependencies(Objectbean)throwsException{Class?clazzbean.getClass();for(Fieldfield:clazz.getDeclaredFields()){// 1. 检查是否有 MyAutowiredif(field.isAnnotationPresent(MyAutowired.class)){field.setAccessible(true);// 2. 获取依赖类型Class?fieldTypefield.getType();StringbeanNamefieldType.getSimpleName();// 3. 从容器获取 BeanObjectdependencybeans.get(beanName);if(dependencynull){thrownewRuntimeException(未找到依赖 Bean: beanName);}// 4. 注入字段field.set(bean,dependency);}}}}3. 测试注入// 1. 定义 DaoclassUserDao{publicvoidsave(){System.out.println(UserDao.save);}}// 2. 定义 ServiceclassUserService{MyAutowiredprivateUserDaouserDao;// 自动注入publicvoidcreateUser(){userDao.save();}}// 3. 启动容器UserDaodaonewUserDao();UserServiceservicenewUserService();SimpleContainer.registerBean(dao);SimpleContainer.registerBean(service);SimpleContainer.injectDependencies(service);// 执行注入// 4. 调用service.createUser();// 输出UserDao.saveuserDao 已被自动赋值框架关联这就是Spring IOC 容器的核心逻辑扫描 → 创建 Bean → 扫描字段 → 注入依赖五、 今日实战任务注解框架实战任务 1实现参数校验器/** * 要求 * 1. 定义 NotNull 和 Range 注解 * 2. 创建 User 类字段上添加注解 * 3. 实现 Validator.validate() 方法 * 4. 测试传入合法/非法数据观察是否抛异常 * * 挑战 * - 支持嵌套对象校验如 User 中有 Address 字段 * - 支持自定义校验规则接口 */任务 2实现简易日志切面/** * 要求 * 1. 使用第 34 天定义的 Log 注解 * 2. 实现 LogInterceptor.invokeWithLog() 方法 * 3. 统计方法执行耗时 * 4. 测试调用带注解和不带注解的方法对比输出 * * 思考 * - 这种方式需要手动调用拦截器如何用动态代理自动拦截 * - 提示结合第 33 天的动态代理知识 */任务 3实现简易 IOC 容器/** * 要求 * 1. 定义 MyAutowired 注解 * 2. 实现 SimpleContainer 的 registerBean 和 injectDependencies * 3. 创建 Service Dao 结构测试依赖注入 * 4. 验证注入后的字段是否不为 null * * 挑战 * - 处理循环依赖问题A 依赖 BB 依赖 A * - 支持按类型注入不只按名称 */任务 4探索 Spring 源码/** * 要求 * 1. 打开 Spring 项目或查看在线源码 * 2. 找到 Autowired 注解定义查看其元注解 * 3. 找到 ClassUtils 或 ReflectionUtils 类查看 Spring 如何读取注解 * 4. 记录Spring 用了哪些反射工具方法 * * 提示 * 关注 AnnotatedElementUtils 类 */ 第 35 天 · 核心总结极简背诵版反射读取注解clazz.isAnnotationPresent(Ann.class)clazz.getAnnotation(Ann.class)method.getAnnotation(Ann.class)// ⚠️ 必须 Retention(RUNTIME)三大应用场景参数校验NotNull/Range → 反射检查字段值 日志切面Log → 反射调用方法前后增强 依赖注入Autowired → 反射设置字段值框架原理映射Hibernate Validator ← 参数校验 Spring AOP ← 日志切面 Spring IOC ← 依赖注入性能注意✅ 缓存反射对象Class/Method/Field✅ 缓存注解信息避免重复读取❌ 避免在高频循环中反射读取注解明天预告️Lombok 实战 阶段总结—— 提升开发效率的利器Lombok 核心注解Data/Builder/Slf4jLombok 原理注解处理器 APT注意事项与避坑指南第 3 阶段总结设计模式与注解知识脑图准备好了吗明天我们用工具解放双手并结束本阶段学习 ✨

相关文章:

JAVA重点基础、进阶知识及易错点总结(35)注解与反射

🚀 Java 巩固进阶 第 35 天 主题:注解与反射结合 —— 让注解"活"起来📅 进度概览:继昨天学习注解定义之后,今天进入 注解的核心应用场景:注解 反射。单独的注解只是"标签"&#xff…...

AI率超80%不要慌,这样处理比自己改快10倍

看到AI率80%,第一反应是慌乱,这完全正常。但慌乱之后,做什么决定很关键。 这篇文章只说一件事:为什么用工具处理比自己改快10倍,怎么用工具最快解决这个问题。 手动改写的真实速度 先来做一个计算。 一个写作速度正…...

JAVA重点基础、进阶知识及易错点总结(34)注解基础(Annotation)

🚀 Java 巩固进阶 第 34 天 主题:注解基础(Annotation)—— 代码的"元数据"标签📅 进度概览:继设计模式之后,今天学习 Java 注解体系。注解是"代码的标签",是 …...

AI 编程 Harness 框架深度拆解(非常详细),6 大框架从入门到精通,收藏这一篇就够了!

AI 会写,不等于 AI 能稳定交付。 前段时间我们都在说 Vibe Coding,大家都知道是氛围编程的意思,但是现在也有叫“直觉编程”。什么叫直觉编程,就是完全不用管其它的,想到什么就做什么,主打一个靠直觉写代码…...

多模态整合进阶必读:MIT APOLLO框架核心思想(非常详细),从原理到精通,收藏这一篇就够了!

麻省理工学院与瑞士苏黎世联邦理工学院的联合研究团队,提出了计算框架 APOLLO,即通过潜变量优化学习部分重叠潜空间的自编码器,其通过显式建模共享信息和模态特异性信息,为更全面、精准地解析细胞状态及其调控逻辑提供了一条可行的…...

初试FreeRTOS:创建上位机接收数据驱动4个舵机任务,如裸机般无感

解析函数上位机数据协议:协议格式 (LD150舵机)[0x55][0x55][ID][长度][命令][数据...][校验和]2字节 1字节 1字节 1字节 N字节 1字节帧头: 0x55 0x55 ID: 舵机ID (1-4) 或 0xFE (广播) 数据: 每组5字节 ID time_low time_high pos_low pos_high 位置: …...

GraphRAG退场了,BookRAG知识像翻书一样简单

你是否曾面对一本厚厚的说明书、技术手册或学术著作,在寻找某个具体信息时感到无从下手?传统的检索增强生成(RAG)方法在处理这类结构复杂的长文档时,常常力不从心。它们要么将文档视为一盘散沙的文本,丢失了…...

7张图讲透Claude Code架构(非常详细),Harness设计从入门到精通,收藏这一篇就够了!

1. 整体概述 众所周知,Claude Code不仅仅是Coding产品,更是一个通用的终端Agent:能循环思考、调度工具、治理权限、恢复上下文、稳定长会话… 如何研读项目源码呢? 首先,我让AI帮着梳理了下目录架构和模块职责&…...

02_Elasticsearch知识体系之Mapping映射设计与索引建模实战

02_Elasticsearch知识体系之Mapping映射设计与索引建模实战 Elasticsearch知识体系 基础概念层数据存储层【本文】查询语言层搜索能力层数据处理层集群架构层开发集成层AI增强层行业应用层 关键词: Elasticsearch、Mapping、动态映射、显式映射、字段类型、分片、副…...

四开关Buck-Boost双向DC-DC电源系统全套学习资料:STM32F334C8T6控制下...

四开关Buck-Boost双向DC-DC电源整套学习资料 功能:采用STM32F334C8T6芯片,能够根据输入电压和输出电压的大小关系,实现自动切换工作模式,将参数信息进行显示,并且可以实现稳压输出 程序仿真硬件软件说明报告原理图计算…...

COMSOL水力压裂岩石多裂隙损伤耦合模型及含离散裂隙Matlab建模文件

comsol水力压裂岩石多裂隙损伤耦合模型,含离散裂隙matlab建模文件地下三千米的页岩层正在经历一场暴力美学——高压水柱像手术刀般精准切开岩石,形成错综复杂的裂缝网络。这个看似野蛮的过程背后,隐藏着流-固-损伤三场耦合的精密舞蹈。今天我…...

STM32F107单片机驱动Dp83848以太网芯片程序 项目开发用到了Dp83848这一个以...

STM32F107单片机驱动Dp83848以太网芯片程序 项目开发用到了Dp83848这一个以太网芯片,本人发现其配置起来比较麻烦,所以整理了一份STM32F107单片机驱动Dp83848的程序代码例程,方便大家学习相关代码的配置最近在项目里折腾STM32F107和DP83848这…...

基于MATLAB的多种概率分布拟合与KS检验:从GEV到Exponential分布选择与实践

11种概率分布的拟合与ks检验,可用于概率分析,可靠度计算等领域 案例中提供11种概率分布,具体包括:gev、logistic、gaussian、tLocationScale、Rayleigh、Loglogistic、Lognormal、GeneralizedPareto、Weibull、Gamma、Exponential…...

如何高效构建Steam游戏DRM解除自动化解决方案:开源框架技术实现

如何高效构建Steam游戏DRM解除自动化解决方案:开源框架技术实现 【免费下载链接】Steam-auto-crack Steam Game Automatic Cracker 项目地址: https://gitcode.com/gh_mirrors/st/Steam-auto-crack Steam游戏DRM解除自动化解决方案为技术爱好者提供了一套完整…...

3步彻底解决Windows多显示器DPI缩放难题:SetDPI工具完全指南

3步彻底解决Windows多显示器DPI缩放难题:SetDPI工具完全指南 【免费下载链接】SetDPI 项目地址: https://gitcode.com/gh_mirrors/se/SetDPI 还在为Windows系统下多显示器DPI缩放不一致而烦恼吗?主显示器清晰锐利,副显示器却模糊不堪…...

跳点搜索算法(JPS)融合动态窗口法,JPS规划全局路径,动态窗口法执行动态避障

跳点搜索算法(JPS)融合动态窗口法,JPS规划全局路径,动态窗口法执行动态避障最近在搞机器人路径规划,总得在效率和安全之间找平衡。今天聊点实战的——把跳点搜索(JPS)和动态窗口法(D…...

claw-code 源码详细分析:子系统目录地图——几十个顶层包如何用五条轴(会话 / 工具 / 扩展 / 入口 / 桥接)读懂?

范围:src/ 下 顶层包(含 */__init__.py 的目录)与 与会话/runtime 强相关的根模块;与 result/01_start.md 第十三节、「清单—路由—会话」叙事一致。1. 为什么用五条轴 src/ 里同时存在: 大量占位包(读 re…...

S7-200 MCGS 基于PLC的小型水厂恒压供水系统 带解释的梯形图接线图原理图图纸,io分配

S7-200 MCGS 基于PLC的小型水厂恒压供水系统 带解释的梯形图接线图原理图图纸,io分配,组态画面最近在搞一个小型水厂的恒压供水系统项目,用西门子S7-200 PLC搭配MCGS组态软件,效果挺有意思的。这个系统核心就仨字——稳如狗&#…...

全贴合工艺中Cover Lens Mura不良的关键影响因素与优化策略

1. 全贴合工艺中的Mura现象解析 第一次看到全贴合屏幕上出现发黄或发白的斑块时,我还以为是产品运输途中受了撞击。后来在产线蹲守三个月才发现,这些被称为"Mura"的光学缺陷,其实是贴合工艺中的隐形杀手。Mura这个词源自日语"…...

深入解析build.prop:从基础参数到高级定制指南

1. build.prop文件到底是什么? 第一次在Android系统目录里看到build.prop这个文件时,我也是一头雾水。这玩意儿看起来就像个普通的文本文件,但里面密密麻麻的参数却让人望而生畏。后来才发现,它其实是Android系统的"身份证&q…...

别只盯着TCP!拆解大疆源码里MQTT协议的双通道设计:BASIC与DRC到底有啥区别?

大疆源码中的MQTT双通道设计:BASIC与DRC的工程哲学 在分析大疆无人机开源项目的通信架构时,一个有趣的设计选择跃然眼前——MQTT协议同时运行在TCP和WebSocket两种传输层上。这种看似冗余的配置背后,隐藏着对物联网通信场景的深刻理解。本文将…...

一台机器也能玩转StarRocks?手把手教你搭建单机测试环境(附避坑指南)

一台机器玩转StarRocks:单机测试环境搭建实战与避坑指南 当你想快速验证StarRocks的功能特性,或者进行本地开发测试时,单机部署是最便捷的选择。虽然官方并不推荐在生产环境中使用单机模式,但对于个人开发者、学生或测试场景来说&…...

一次删错索引引发的血案:手把手教你复盘线上购物车故障(附完整报告模板)

一次删错索引引发的血案:手把手教你复盘线上购物车故障 那天凌晨3点,我被刺耳的电话铃声惊醒。值班同事急促的声音从听筒传来:"购物车服务完全瘫痪,用户投诉像雪片一样涌来。"当我跌跌撞撞赶到公司时,整个技…...

从零搭建WebRTC SFU服务器:基于Mediasoup的1080P视频会议部署教程

从零搭建WebRTC SFU服务器:基于Mediasoup的1080P视频会议部署教程 视频会议已成为现代远程协作的核心工具,而WebRTC技术让浏览器间的实时音视频通信变得触手可及。但当你需要支持10人以上的高清会议时,单纯的P2P连接就会暴露出带宽和性能瓶颈…...

Claude Code 接入 DeepSeek、GLM、MiniMax 等国产大模型,保姆级教程!

每天免费领 1亿 Token,白嫖DeepSeek、GLM、MiniMax、Kimi等大模型! 这份指南是专门为那些“只想赶紧上手开干”的朋友准备的。 咱们不整那些虚头巴脑的理论,直接帮你搞定这几件事: 怎么把 Claude Code 装好如何确定它已经能跑通…...

拆解Clonezilla镜像:除了partclone,你还需要知道的底层原理与工具链

拆解Clonezilla镜像:从分卷压缩到文件系统的技术全景解析 当我们需要从Clonezilla备份中提取单个文件时,传统方法往往要求完整恢复整个镜像——这种"全有或全无"的方式在存储资源有限的情况下显得尤为笨重。本文将带您深入Clonezilla镜像的底层…...

CSS 语音参考

CSS 语音参考 概述 CSS(层叠样式表)是网页设计中的核心组成部分,它允许开发者控制网页元素的样式,包括颜色、布局、字体等。在网页设计中,有时我们需要为特定的元素添加语音提示,以便于视觉障碍者或需要语音辅助的用户使用。本文将详细探讨CSS中语音参考的实现方法,包…...

AngularJS Http详解

AngularJS Http详解 引言 AngularJS是一个流行的JavaScript框架,用于构建动态和响应式的web应用。在AngularJS中,HTTP请求是数据交互的重要组成部分。本文将详细介绍AngularJS的Http服务,包括其基本用法、高级特性以及如何处理异步请求。 AngularJS Http服务简介 Angula…...

网站主机技术概述

网站主机技术概述 随着互联网技术的飞速发展,网站已经成为企业和个人展示形象、提供服务的必要平台。网站主机的选择对于网站的稳定性和访问速度至关重要。本文将详细阐述网站主机技术,包括其基本概念、类型、选择标准以及未来发展趋势。 一、网站主机基本概念 网站主机,…...

《Foundation 网格 - 大型设备》

《Foundation 网格 - 大型设备》 引言 在当今科技日新月异的时代,大型设备在各个领域都扮演着至关重要的角色。其中,Foundation 网格作为一项创新技术,正在逐渐改变着我们的生产方式和生活质量。本文将深入探讨Foundation 网格的特点、应用以及未来发展趋势。 一、Founda…...