来了,这一篇我们直接走**“从 0 到能写框架级代码”的路线 😎
不是只讲语法,而是注解 + 反射 = 真正能干活的武器**
Java 注解与反射实战
自定义注解从入门到精通
一句话定位:
看完这篇,你能读懂 Spring 注解原理,也能自己造一个轻量框架
一、为什么 Java 离不开注解 + 反射?
先看一个熟到不能再熟的东西👇
@RestController
@RequestMapping("/user")
public class UserController {
}
问题是:
- Java 本身不会“认识”注解
- 真正起作用的,是——反射
👉 本质公式:
注解 = 元数据
反射 = 读取 + 执行元数据
二、注解基础速通(必须掌握)
1️⃣ 注解是什么?
注解是一种 写在代码里的结构化配置
@Override
✔ 不影响代码逻辑
✔ 可被工具 / 框架读取
✔ 比 XML / 配置文件更安全
2️⃣ 注解能写在哪?
| 位置 | Target |
|---|---|
| 类 | TYPE |
| 方法 | METHOD |
| 成员变量 | FIELD |
| 参数 | PARAMETER |
| 构造器 | CONSTRUCTOR |
三、元注解(定义注解的注解)⭐ 必背
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}
四大核心元注解
| 元注解 | 作用 |
|---|---|
| @Target | 注解能用在哪 |
| @Retention | 生命周期 |
| @Documented | 是否进 javadoc |
| @Inherited | 子类是否继承 |
Retention 三种级别(高频考点)
| 类型 | 说明 |
|---|---|
| SOURCE | 编译后丢弃 |
| CLASS | 编译进 class,不运行 |
| RUNTIME | 运行期可反射(最重要) |
📌 只要和反射有关,必须是 RUNTIME
四、自定义注解入门(动手)
1️⃣ 定义一个注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
String value() default "";
}
规则:
- 注解方法 ≈ 属性
- 只能有返回值,不能有参数
- 支持 default
2️⃣ 使用注解
@Log("用户登录")
public void login() {
}
五、反射基础(注解的发动机)
1️⃣ 获取 Class 对象
Class<?> clazz = UserService.class;
2️⃣ 获取方法 & 注解
Method method = clazz.getDeclaredMethod("login");
Log log = method.getAnnotation(Log.class);
System.out.println(log.value());
👉 注解此刻才真正“生效”
六、完整实战:自定义日志注解 ⭐⭐⭐
🎯 目标
- 方法上加
@Log - 自动打印日志内容
1️⃣ 注解定义
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
String value();
}
2️⃣ 业务方法
public class UserService {
@Log("执行登录逻辑")
public void login() {
System.out.println("login...");
}
}
3️⃣ 反射处理器(核心)
public class LogProcessor {
public static void process(Object obj) throws Exception {
Class<?> clazz = obj.getClass();
for (Method method : clazz.getDeclaredMethods()) {
if (method.isAnnotationPresent(Log.class)) {
Log log = method.getAnnotation(Log.class);
System.out.println("日志:" + log.value());
method.invoke(obj);
}
}
}
}
4️⃣ 调用
LogProcessor.process(new UserService());
🎉 一个注解驱动功能完成
七、进阶:注解 + 反射的 5 个高级用法
1️⃣ 参数校验(Hibernate Validator 原理)
@NotNull
@Length(max = 20)
2️⃣ 权限控制
@RequireRole("ADMIN")
3️⃣ 自动注入(IOC 雏形)
@Inject
private UserService userService;
4️⃣ 接口映射(Spring MVC 原理)
@RequestMapping("/login")
5️⃣ 配置替代 XML
约定 > 配置 > 注解
八、注解 vs 接口 vs 抽象类(别搞混)
| 对比 | 注解 | 接口 |
|---|---|---|
| 是否有逻辑 | ❌ | ❌ |
| 是否强约束 | ❌ | ✅ |
| 主要用途 | 元数据 | 行为规范 |
📌 注解不参与继承体系
九、常见坑(面试 + 实战)
1️⃣ 忘记 Retention.RUNTIME
2️⃣ 用反射却拿不到注解
3️⃣ getMethod vs getDeclaredMethod 混用
4️⃣ 注解不是魔法,没反射=没用
5️⃣ 过度设计,小项目别滥用
十、一句话终极总结(建议背)
注解是标签,反射是解释器
没有反射,注解只是注释
下一步你可以继续冲 🚀
我可以直接带你:
- 🔥 手写一个 mini Spring(IOC + 注解)
- 🧠 彻底看懂 Spring 注解启动流程
- 🧪 注解 + AOP 实战
- 📚 注解 / 反射 面试必问 30 题
你想往 框架原理 / 实战项目 / 面试突击 哪个方向继续?