本文目录导读:

我将为您提供几个Java自定义注解的完整案例,从基础到进阶。
基础注解定义案例
1 简单的标记注解
import java.lang.annotation.*;
// 定义注解
@Target(ElementType.METHOD) // 注解只能用于方法
@Retention(RetentionPolicy.RUNTIME) // 运行时保留
public @interface LogExecutionTime {
}
2 带参数的注解
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestLog {
String value() default ""; // 请求描述
String module() default "default"; // 模块名称
boolean logParams() default true; // 是否记录参数
Level level() default Level.INFO; // 日志级别
enum Level {
DEBUG, INFO, WARN, ERROR
}
}
注解处理器案例
1 日志记录注解处理器
import java.lang.reflect.Method;
import java.util.Arrays;
public class LogProcessor {
public static void processLog(Object obj) {
Class<?> clazz = obj.getClass();
for (Method method : clazz.getDeclaredMethods()) {
if (method.isAnnotationPresent(LogExecutionTime.class)) {
long start = System.currentTimeMillis();
try {
System.out.println("开始执行方法: " + method.getName());
// 这里可以继续处理invoke等逻辑
} finally {
long duration = System.currentTimeMillis() - start;
System.out.println("方法 " + method.getName() + " 执行耗时: " + duration + "ms");
}
}
}
}
}
2 字段验证注解处理器
import java.lang.annotation.*;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
// 定义验证注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Required {
String message() default "字段不能为空";
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Length {
int min() default 0;
int max() default Integer.MAX_VALUE;
String message() default "长度不符合要求";
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EmailFormat {
String message() default "邮箱格式不正确";
}
// 验证处理器
public class ValidatorProcessor {
private static final String EMAIL_REGEX = "^[A-Za-z0-9+_.-]+@(.+)$";
public static List<String> validate(Object obj) throws IllegalAccessException {
List<String> errors = new ArrayList<>();
for (Field field : obj.getClass().getDeclaredFields()) {
field.setAccessible(true);
String fieldName = field.getName();
Object value = field.get(obj);
// 必填验证
if (field.isAnnotationPresent(Required.class)) {
if (value == null || value.toString().trim().isEmpty()) {
Required required = field.getAnnotation(Required.class);
errors.add(fieldName + ": " + required.message());
}
}
// 长度验证
if (field.isAnnotationPresent(Length.class) && value != null) {
Length length = field.getAnnotation(Length.class);
int stringLength = value.toString().length();
if (stringLength < length.min() || stringLength > length.max()) {
errors.add(fieldName + ": " + length.message());
}
}
// 邮箱验证
if (field.isAnnotationPresent(EmailFormat.class) && value != null) {
EmailFormat emailFormat = field.getAnnotation(EmailFormat.class);
if (!value.toString().matches(EMAIL_REGEX)) {
errors.add(fieldName + ": " + emailFormat.message());
}
}
}
return errors;
}
}
实际应用案例
1 用户实体类
public class User {
@Required(message = "用户名不能为空")
@Length(min = 3, max = 20, message = "用户名长度必须在3-20之间")
private String username;
@Required(message = "密码不能为空")
@Length(min = 6, max = 30, message = "密码长度必须在6-30之间")
private String password;
@EmailFormat(message = "必须是有效的邮箱地址")
private String email;
public User(String username, String password, String email) {
this.username = username;
this.password = password;
this.email = email;
}
// getter和setter方法
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
}
2 业务服务类
import java.lang.reflect.Method;
public class UserService {
@LogExecutionTime
@RequestLog(value = "创建用户", module = "user", logParams = true, level = RequestLog.Level.INFO)
public User createUser(String username, String password, String email) throws Exception {
// 模拟业务逻辑
User user = new User(username, password, email);
// 执行验证
List<String> errors = ValidatorProcessor.validate(user);
if (!errors.isEmpty()) {
throw new Exception("验证失败: " + String.join(", ", errors));
}
// 模拟数据库操作
System.out.println("保存用户到数据库: " + username);
return user;
}
@LogExecutionTime
public User getUser(String username) {
System.out.println("查询用户: " + username);
return new User(username, "password123", "test@example.com");
}
@RequestLog(value = "删除用户", module = "user", logParams = true, level = RequestLog.Level.WARN)
public void deleteUser(String username) {
System.out.println("删除用户: " + username);
}
}
3 注解处理器测试类
import java.lang.reflect.Method;
public class AnnotationDemo {
public static void main(String[] args) throws Exception {
// 1. 测试日志注解处理
UserService userService = new UserService();
LogProcessor.processLog(userService);
// 2. 测试验证注解
User validUser = new User("张三", "123456", "zhangsan@example.com");
User invalidUser1 = new User("", "123", "invalid-email");
User invalidUser2 = new User("李", "123456", "lisi@example.com");
// 验证有效用户
List<String> validErrors = ValidatorProcessor.validate(validUser);
System.out.println("有效用户验证结果:");
if (validErrors.isEmpty()) {
System.out.println("✓ 验证通过");
} else {
System.out.println("✗ 验证失败: " + String.join(", ", validErrors));
}
System.out.println("\n无效用户验证结果:");
// 验证无效用户1
List<String> errors1 = ValidatorProcessor.validate(invalidUser1);
errors1.forEach(error -> System.out.println("✗ " + error));
System.out.println();
// 验证无效用户2
List<String> errors2 = ValidatorProcessor.validate(invalidUser2);
errors2.forEach(error -> System.out.println("✗ " + error));
// 3. 批量创建用户
try {
userService.createUser("王五", "password123", "wangwu@example.com");
System.out.println("用户创建成功");
} catch (Exception e) {
System.out.println("用户创建失败: " + e.getMessage());
}
}
}
元注解说明
import java.lang.annotation.*;
// @Target: 指定注解可以使用的元素位置
// 常用的取值:
@Target({ElementType.TYPE, // 类、接口、枚举
ElementType.FIELD, // 字段
ElementType.METHOD, // 方法
ElementType.PARAMETER, // 参数
ElementType.CONSTRUCTOR, // 构造方法
ElementType.LOCAL_VARIABLE}) // 局部变量
@Retention(RetentionPolicy.RUNTIME) // 何时保留注解
// RetentionPolicy.SOURCE - 只在源代码中保留,编译后被丢弃
// RetentionPolicy.CLASS - 编译时保留,但运行时不可见(默认)
// RetentionPolicy.RUNTIME - 运行时保留,可以通过反射读取
@Documented // 是否包含在javadoc中
@Inherited // 是否允许子类继承
public @interface ComprehensiveAnnotation {
// 注解元素类似方法
String name() default "default";
int value() default 0;
}
最佳实践建议
// 1. 使用常量定义默认值
public final class AnnotationConstants {
public static final String DEFAULT_VALUE = "default_value";
public static final int DEFAULT_NUMBER = 0;
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface BestPractice {
String value() default AnnotationConstants.DEFAULT_VALUE;
int number() default AnnotationConstants.DEFAULT_NUMBER;
}
// 2. 注解处理器实现接口模式
public interface AnnotationProcessor<T> {
void process(T annotation, Object target);
}
// 3. 注解使用示例最佳实践
@Service
public class BestPracticeExample {
@Autowired // Spring框架注解
private UserRepository userRepository;
@Transactional
public void transactionalMethod() {
// 方法实现
}
}
测试运行结果示例
开始执行方法: createUser 保存用户到数据库: 王五 方法 createUser 执行耗时: 2ms 创建用户成功 有效用户验证结果: ✓ 验证通过 无效用户验证结果: ✗ 用户名不能为空 ✗ 密码长度必须在6-30之间 ✗ 必须是有效的邮箱地址 ✗ 用户名长度必须在3-20之间
这些案例涵盖了:
- 注解的基本定义
- 注解参数的使用
- 注解处理器(通过反射)
- 实际业务场景(日志记录、数据验证)
- 元注解的使用
- 最佳实践建议
通过自定义注解,您可以:
- 减少样板代码
- 提供声明式编程方式
- 实现统一的业务逻辑处理
- 提高代码的可读性和可维护性