注解

注解(Annotation)是附加在代码元素上的元数据,本身不改变程序行为,由编译器或运行时框架读取并处理。

内置注解

注解作用
@Override标记方法重写,编译器验证签名
@Deprecated标记已废弃,编译器警告
@SuppressWarnings抑制编译器警告
@FunctionalInterface标记函数式接口,编译器验证只有一个抽象方法
@SafeVarargs抑制泛型可变参数警告
@SuppressWarnings({"unchecked", "deprecation"})
public void oldMethod() { }

元注解

元注解用于修饰自定义注解。

@Target

指定注解可以标注的位置:

@Target({ElementType.METHOD, ElementType.TYPE})
说明
TYPE类、接口、枚举
FIELD字段
METHOD方法
PARAMETER方法参数
CONSTRUCTOR构造器
LOCAL_VARIABLE局部变量
ANNOTATION_TYPE注解类型
PACKAGE
TYPE_PARAMETER类型参数(Java 8)
TYPE_USE类型使用(Java 8)

@Retention

指定注解的生命周期:

说明
SOURCE仅在源码中,编译后丢弃(如 @Override
CLASS保留到 class 文件,运行时不可见(默认)
RUNTIME运行时可通过反射读取(框架常用)

@Documented

注解是否出现在 Javadoc 中。

@Inherited

标注在类上的注解是否被子类继承(仅对类注解有效)。

@Repeatable(Java 8+)

允许同一位置重复使用同一注解:

@Repeatable(Schedules.class)
@interface Schedule {
    String cron();
}
 
@interface Schedules {
    Schedule[] value();
}
 
@Schedule(cron = "0 0 * * *")
@Schedule(cron = "0 12 * * *")
public void task() { }

自定义注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
    String value() default "";          // 操作描述
    boolean recordArgs() default true;  // 是否记录参数
    LogLevel level() default LogLevel.INFO;
}

注解元素类型只能是:基本类型、StringClass、枚举、注解、以上类型的数组。

运行时读取(反射)

// 读取方法上的注解
Method method = UserService.class.getMethod("createUser", User.class);
if (method.isAnnotationPresent(Log.class)) {
    Log log = method.getAnnotation(Log.class);
    System.out.println("操作: " + log.value());
    System.out.println("记录参数: " + log.recordArgs());
}
 
// 读取类上的注解
Class<?> clazz = UserService.class;
Log classLog = clazz.getAnnotation(Log.class);
 
// 读取字段上的注解
for (Field field : clazz.getDeclaredFields()) {
    if (field.isAnnotationPresent(NotNull.class)) {
        System.out.println(field.getName() + " 不能为空");
    }
}
 
// 读取所有注解
Annotation[] annotations = method.getAnnotations();

注解处理器(编译期)

实现 javax.annotation.processing.AbstractProcessor,在编译期处理注解(如 Lombok、MapStruct):

@SupportedAnnotationTypes("com.example.Builder")
@SupportedSourceVersion(SourceVersion.RELEASE_17)
public class BuilderProcessor extends AbstractProcessor {
 
    @Override
    public boolean process(Set<? extends TypeElement> annotations,
                           RoundEnvironment roundEnv) {
        for (Element element : roundEnv.getElementsAnnotatedWith(Builder.class)) {
            // 生成 Builder 类的源码
            generateBuilderClass((TypeElement) element);
        }
        return true;
    }
}

AOP 结合注解(Spring 常用模式)

// 1. 定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimit {
    int qps() default 100;
}
 
// 2. 切面处理
@Aspect
@Component
public class RateLimitAspect {
 
    @Around("@annotation(rateLimit)")
    public Object around(ProceedingJoinPoint pjp, RateLimit rateLimit) throws Throwable {
        String key = pjp.getSignature().toString();
        if (!limiter.tryAcquire(key, rateLimit.qps())) {
            throw new TooManyRequestsException("请求过于频繁");
        }
        return pjp.proceed();
    }
}
 
// 3. 使用
@RateLimit(qps = 10)
public Result<?> queryUser(Long id) { ... }

常用框架注解速查

Spring

注解说明
@Component / @Service / @RepositoryBean 注册
@Autowired / @Resource依赖注入
@Value注入配置值
@Configuration / @BeanJava 配置类
@RequestMapping / @GetMapping路由映射
@Transactional声明式事务
@Cacheable / @CacheEvict缓存
@Scheduled定时任务
@Async异步执行

校验(Jakarta Validation)

注解说明
@NotNull不能为 null
@NotBlank不能为空串
@NotEmpty不能为空集合
@Size(min, max)长度范围
@Min / @Max数值范围
@Email邮箱格式
@Pattern(regexp)正则匹配
@Valid / @Validated触发校验

相关链接