注解
注解(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;
}注解元素类型只能是:基本类型、String、Class、枚举、注解、以上类型的数组。
运行时读取(反射)
// 读取方法上的注解
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 / @Repository | Bean 注册 |
@Autowired / @Resource | 依赖注入 |
@Value | 注入配置值 |
@Configuration / @Bean | Java 配置类 |
@RequestMapping / @GetMapping | 路由映射 |
@Transactional | 声明式事务 |
@Cacheable / @CacheEvict | 缓存 |
@Scheduled | 定时任务 |
@Async | 异步执行 |
校验(Jakarta Validation)
| 注解 | 说明 |
|---|---|
@NotNull | 不能为 null |
@NotBlank | 不能为空串 |
@NotEmpty | 不能为空集合 |
@Size(min, max) | 长度范围 |
@Min / @Max | 数值范围 |
@Email | 邮箱格式 |
@Pattern(regexp) | 正则匹配 |
@Valid / @Validated | 触发校验 |