# 深入理解Java注解,从使用到自定义

Java注解(Annotation)无处不在------@Override、@Test、@Autowired、@RequestMapping......天天在用,但注解到底是怎么工作的?怎么自定义一个?

今天从基础到实战,把注解讲透。

注解的本质

注解本身就是一个接口,继承自java.lang.annotation.Annotation。它不直接影响代码逻辑,只是标记信息,由编译器或框架在编译期/运行时读取。

java 复制代码
// @Override的定义(源码)
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

四个元注解

定义注解时用到的注解叫"元注解":

java 复制代码
@Target(ElementType.METHOD)          // 1. 注解能加在哪里
@Retention(RetentionPolicy.RUNTIME)  // 2. 注解的生命周期
@Documented                          // 3. 是否出现在Javadoc中
@Inherited                           // 4. 是否被子类继承
public @interface MyAnnotation {
    String value() default "";
    int count() default 0;
}

@Target:注解可以修饰的目标

值 含义
TYPE 类/接口/枚举
FIELD 字段
METHOD 方法
PARAMETER 方法参数
CONSTRUCTOR 构造器
LOCAL_VARIABLE 局部变量

@Retention:注解的生命周期

值 含义 能否反射读取
SOURCE 只在源码中 否
CLASS 源码和class文件中 否
RUNTIME 运行时保留 是(最常用)

自定义注解实战

场景:自定义一个权限校验注解

java 复制代码
// 定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequirePermission {
    String value();                    // 权限标识
    boolean required() default true;   // 是否必须
}

// 使用注解
@RestController
public class AdminController {

    @RequirePermission("user:delete")
    @DeleteMapping("/user/{id}")
    public Result deleteUser(@PathVariable Long id) {
        userService.delete(id);
        return Result.ok();
    }

    @RequirePermission(value = "report:view", required = false)
    @GetMapping("/report")
    public Result viewReport() {
        return Result.ok(reportService.getReport());
    }
}

用AOP处理注解逻辑:

java 复制代码
@Aspect
@Component
public class PermissionAspect {

    @Autowired
    private HttpServletRequest request;

    @Around("@annotation(annotation)")
    public Object checkPermission(ProceedingJoinPoint point,
                                   RequirePermission annotation) throws Throwable {
        String permission = annotation.value();

        // 获取当前用户
        String token = request.getHeader("Authorization");
        User currentUser = TokenUtil.parseUser(token);

        // 检查权限
        boolean hasPermission = permissionService.hasPermission(
            currentUser.getId(), permission);

        if (!hasPermission) {
            if (annotation.required()) {
                throw new BusinessException(403, "没有权限: " + permission);
            }
            return Result.ok(); // 非必须,无权限返回空
        }

        return point.proceed(); // 有权限,继续执行
    }
}

通过反射读取注解

java 复制代码
// 读取类上的注解
Class<?> clazz = UserController.class;
RequestMapping classMapping = clazz.getAnnotation(RequestMapping.class);
if (classMapping != null) {
    System.out.println("路径前缀: " + classMapping.value()[0]);
}

// 读取方法上的注解
Method method = clazz.getMethod("getUser", Long.class);
GetMapping getMapping = method.getAnnotation(GetMapping.class);
if (getMapping != null) {
    System.out.println("GET路径: " + getMapping.value()[0]);
}

// 读取参数上的注解
Parameter[] params = method.getParameters();
for (Parameter param : params) {
    PathVariable pv = param.getAnnotation(PathVariable.class);
    if (pv != null) {
        System.out.println("路径参数: " + pv.value());
    }
}

注解和配置的区别

对比 注解 配置文件
位置 代码上 外部文件
修改 需要重新编译 运行时可改
适合 代码级标记(权限、路由) 环境相关配置(数据库、密钥)
灵活性 低 高

实际项目中两者配合使用:注解标记代码逻辑,配置文件管理环境变量。


注解是Java元编程的基础。Spring之所以能做到"约定大于配置",背后大量依赖注解和反射。

理解了注解的原理,看框架源码时就不会一头雾水了。

你们项目中自定义过什么注解?

相关推荐
Flynn Liang13 小时前
Spring AI 2.0 深度解析:ChatClient、Advisor 链与 MCP——Java 工程师的 AI 落地最优解
java·人工智能·spring·大模型·架构设计·spring ai
灿飞13 小时前
Kotlin与Java虚拟机六:基础与类型系统:一切皆对象,但对象有代价
java·kotlin
计算机毕设定制辅导-无忧学长13 小时前
《基于微信小程序健康习惯激励系统设计与实现》
java·spring boot·mysql·微信小程序·uniapp·健康习惯激励系统
雪芽蓝域zzs14 小时前
第 1 章:IDEA 创建 SpringBoot3.5.16 Maven 项目
java·maven·intellij-idea
golang学习记14 小时前
IDEA 开始换芯,发布全新AI版终端
java·人工智能·intellij-idea
vipxieliang14 小时前
ValidX 正则表达式预编译优化:Pattern 复用策略
java·spring boot·后端
Wang's Blog15 小时前
Java 项目实战:交友项目 - FastDFS 工作原理
java·大数据·交友
Wang's Blog15 小时前
Java 项目实战:交友项目 - 保存访客记录
java·开发语言·交友
liangbo715 小时前
Spring系列01:IoC 与 DI 到底解决了什么
java·spring
江湖中的阿龙15 小时前
Oracle 紧急安全警报:Java 9.1 分漏洞 CVE-2026-91403,撤销对 eMudhra 风险证书的信任
java·安全·oracle