Java自定义注解案例

wen java案例 4

本文目录导读:

Java自定义注解案例

  1. 基础注解定义案例
  2. 注解处理器案例
  3. 实际应用案例
  4. 元注解说明
  5. 最佳实践建议
  6. 测试运行结果示例

我将为您提供几个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之间

这些案例涵盖了:

  • 注解的基本定义
  • 注解参数的使用
  • 注解处理器(通过反射)
  • 实际业务场景(日志记录、数据验证)
  • 元注解的使用
  • 最佳实践建议

通过自定义注解,您可以:

  • 减少样板代码
  • 提供声明式编程方式
  • 实现统一的业务逻辑处理
  • 提高代码的可读性和可维护性

抱歉,评论功能暂时关闭!