@Retention 注解是 Java 注解机制的一个核心部分,它定义了注解的保留策略,即注解在代码的哪个阶段仍然有效。

注解保留策略

Java 中有三种注解保留策略,分别是:

  1. SOURCE:注解只在源码阶段保留,在编译时被忽略。
  2. CLASS:注解在编译时被保留(包含在类文件中),但在运行时被忽略。
  3. RUNTIME:注解在运行时保留,可以通过反射机制读取。

@Retention 注解的使用如下:

@Retention(RetentionPolicy.RUNTIME)
public @interface YourAnnotation {
    // 注解元素定义
}

运行时注解的用途

@Retention(RetentionPolicy.RUNTIME) 用于那些需要在运行时通过反射读取的注解。它的应用场景包括:

  1. 自定义注解处理:创建运行时注解并在运行时通过反射检索。
  2. 框架与库:框架(如 Spring)使用运行时注解进行配置和定义行为。
  3. API 设计:在公共 API 中使用运行时注解提供元数据。

示例:自定义运行时注解

定义一个注解 @CustomAnnotation 并在运行时通过反射获取其信息:

@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {
    String value();
}
 
public class MyClass {
    @CustomAnnotation(value = "Example")
    public void myMethod() {
        // 方法实现
    }
}
 
// 运行时反射示例
Class<?> clazz = MyClass.class;
Method method = clazz.getMethod("myMethod");
CustomAnnotation annotation = method.getAnnotation(CustomAnnotation.class);
if (annotation != null) {
    // 处理注解信息
}
 

示例:Spring中实现@GetMapping

框架编写中的应用:RESTful API 映射

在像 Spring 这样的框架中,注解被广泛用于定义如何将 HTTP 请求映射到具体的方法。

自定义注解 @GETMapping

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) // 应用于方法
public @interface GETMapping {
    String value();
}
 

使用该注解定义端点

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) // 应用于方法
public @interface GETMapping {
    String value();
}

框架内部处理逻辑

框架内部将使用反射来查找使用 @GETMapping 注解的方法,并根据注解中定义的路径和 HTTP 方法将相应的 HTTP 请求映射到这些方法上。

public class RequestHandler {
    // 假设此方法由框架在接收到 HTTP 请求时调用
    public void handleRequest(String path, String httpMethod) {
        // 查找匹配的方法并调用
        // 这里的逻辑只是简化示例
        for (Method method : UserController.class.getDeclaredMethods()) {
            if (method.isAnnotationPresent(GETMapping.class)) {
                GETMapping getMapping = method.getAnnotation(GETMapping.class);
                if (getMapping.value().equals(path) && "GET".equals(httpMethod)) {
                    // 调用该方法
                }
            }
        }
    }
}