Java注解(Annotation)深度解析:从元编程到框架设计

引言:注解------Java的元编程利器

注解(Annotation)是Java 5引入的一项革命性特性,它允许我们在代码中添加元数据信息,这些信息可以被编译器、开发工具和运行时环境读取和使用。从简单的@Override到复杂的Spring框架注解,注解已经成为现代Java开发的基石。

一、注解基础与内置注解

1.1 Java内置注解详解

java 复制代码
import java.util.*;

// 演示Java内置注解
public class BuiltInAnnotations {
    
    // 1. @Override - 确保方法正确重写父类方法
    @Override
    public String toString() {
        return "BuiltInAnnotations实例";
    }
    
    // 2. @Deprecated - 标记已过时的元素
    @Deprecated(
        since = "2.0",
        forRemoval = true
    )
    public void oldMethod() {
        System.out.println("这是过时的方法,将在未来版本移除");
    }
    
    // 3. @SuppressWarnings - 抑制编译器警告
    @SuppressWarnings({"unchecked", "rawtypes"})
    public void suppressWarningsExample() {
        List list = new ArrayList();  // 没有泛型的List
        list.add("字符串");           // 会产生警告,但被抑制
    }
    
    // 4. @SafeVarargs - 标记可变参数方法是安全的
    @SafeVarargs
    public static final <T> List<T> asList(T... elements) {
        return new ArrayList<>(Arrays.asList(elements));
    }
    
    // 5. @FunctionalInterface - 标记函数式接口(Java 8+)
    @FunctionalInterface
    interface Calculator {
        int calculate(int a, int b);
        
        // 可以有默认方法
        default void printResult(int result) {
            System.out.println("结果: " + result);
        }
        
        // 可以有静态方法
        static Calculator create() {
            return (a, b) -> a + b;
        }
        
        // 可以重写Object的方法,不计入抽象方法计数
        @Override
        boolean equals(Object obj);
    }
    
    // 6. @Generated - 标记自动生成的代码
    @javax.annotation.Generated(
        value = "code-generator",
        date = "2024-01-01T10:00:00",
        comments = "自动生成的代码"
    )
    public class GeneratedClass {
        // 自动生成的代码
    }
    
    // 演示注解的目标限制
    public static void main(String[] args) {
        BuiltInAnnotations demo = new BuiltInAnnotations();
        
        // 使用过时方法会有警告
        demo.oldMethod();
        
        // 查看注解信息
        System.out.println("=== 注解信息 ===");
        
        try {
            // 获取@Override注解信息
            Method toStringMethod = BuiltInAnnotations.class.getMethod("toString");
            if (toStringMethod.isAnnotationPresent(Override.class)) {
                System.out.println("toString方法使用了@Override注解");
            }
            
            // 获取@Deprecated注解信息
            Method oldMethod = BuiltInAnnotations.class.getMethod("oldMethod");
            Deprecated deprecated = oldMethod.getAnnotation(Deprecated.class);
            if (deprecated != null) {
                System.out.println("oldMethod已过时,since: " + deprecated.since());
                System.out.println("是否计划移除: " + deprecated.forRemoval());
            }
            
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
    
    // 7. 重复注解演示(Java 8+)
    // 需要先定义容器注解
    @Repeatable(Authors.class)
    @interface Author {
        String name();
        String email();
    }
    
    @interface Authors {
        Author[] value();
    }
    
    // 使用重复注解
    @Author(name = "张三", email = "zhangsan@example.com")
    @Author(name = "李四", email = "lisi@example.com")
    class Book {
        private String title;
        
        public Book(String title) {
            this.title = title;
        }
    }
    
    // 8. 类型注解(Java 8+)
    // 可以注解在任何类型使用的地方
    void typeAnnotationExample(
        @javax.annotation.NonNull String name,   // 参数不为null
        List<@javax.annotation.NonNull String> list,  // 列表元素不为null
        @javax.annotation.Nullable Integer count  // 参数可以为null
    ) {
        // 方法体
    }
}

1.2 元注解:注解的注解

java 复制代码
import java.lang.annotation.*;

// 自定义元注解演示
public class MetaAnnotations {
    
    // 1. @Retention - 指定注解的保留策略
    @Retention(RetentionPolicy.SOURCE)   // 仅源码级别,编译后丢弃
    @interface SourceAnnotation {}
    
    @Retention(RetentionPolicy.CLASS)    // 类文件级别,运行时不可见
    @interface ClassAnnotation {}
    
    @Retention(RetentionPolicy.RUNTIME)  // 运行时可见(最常用)
    @interface RuntimeAnnotation {}
    
    // 2. @Target - 指定注解可以应用的元素类型
    @Target(ElementType.TYPE)            // 类、接口、枚举
    @interface TypeAnnotation {}
    
    @Target(ElementType.FIELD)           // 字段
    @interface FieldAnnotation {}
    
    @Target(ElementType.METHOD)          // 方法
    @interface MethodAnnotation {}
    
    @Target(ElementType.PARAMETER)       // 参数
    @interface ParameterAnnotation {}
    
    @Target(ElementType.CONSTRUCTOR)     // 构造器
    @interface ConstructorAnnotation {}
    
    @Target(ElementType.LOCAL_VARIABLE)  // 局部变量
    @interface LocalVarAnnotation {}
    
    @Target(ElementType.ANNOTATION_TYPE) // 注解类型
    @interface AnnotationTypeAnnotation {}
    
    @Target(ElementType.PACKAGE)         // 包
    @interface PackageAnnotation {}
    
    @Target(ElementType.TYPE_PARAMETER)  // 类型参数(Java 8+)
    @interface TypeParameterAnnotation {}
    
    @Target(ElementType.TYPE_USE)        // 类型使用(Java 8+)
    @interface TypeUseAnnotation {}
    
    @Target({ElementType.METHOD, ElementType.FIELD}) // 多个目标
    @interface MultiTargetAnnotation {}
    
    // 3. @Documented - 包含在JavaDoc中
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @interface DocumentedAnnotation {
        String value() default "";
    }
    
    // 4. @Inherited - 允许子类继承注解
    @Inherited
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @interface InheritedAnnotation {
        String value();
    }
    
    // 5. @Repeatable - 允许重复注解(Java 8+)
    // 已在上面的BuiltInAnnotations中演示
    
    // 应用示例
    @TypeAnnotation
    @InheritedAnnotation("父类")
    class ParentClass {
        @FieldAnnotation
        private String name;
        
        @MethodAnnotation
        @DocumentedAnnotation("这是方法")
        public void method(@ParameterAnnotation String param) {
            @LocalVarAnnotation
            int localVar = 0;
        }
        
        @ConstructorAnnotation
        public ParentClass() {}
    }
    
    // 子类继承@InheritedAnnotation
    class ChildClass extends ParentClass {
        // 自动继承@InheritedAnnotation("父类")
    }
    
    // 类型参数注解(Java 8+)
    class GenericClass<@TypeParameterAnnotation T> {
        private List<@TypeUseAnnotation T> items;
    }
    
    // 包注解需要特殊的package-info.java文件
    // package-info.java内容示例:
    /*
    @PackageAnnotation
    package com.example;
    
    import com.example.MetaAnnotations.PackageAnnotation;
    */
    
    public static void main(String[] args) {
        System.out.println("=== 元注解演示 ===");
        
        // 检查继承注解
        System.out.println("\n1. 检查继承注解:");
        System.out.println("ParentClass有@InheritedAnnotation: " + 
            ParentClass.class.isAnnotationPresent(InheritedAnnotation.class));
        System.out.println("ChildClass有@InheritedAnnotation: " + 
            ChildClass.class.isAnnotationPresent(InheritedAnnotation.class));
        System.out.println("ChildClass有@TypeAnnotation: " + 
            ChildClass.class.isAnnotationPresent(TypeAnnotation.class));
        
        // 检查文档化注解
        System.out.println("\n2. 检查注解是否文档化:");
        Annotation[] parentAnnotations = ParentClass.class.getAnnotations();
        for (Annotation ann : parentAnnotations) {
            boolean isDocumented = ann.annotationType()
                .isAnnotationPresent(Documented.class);
            System.out.println(ann.annotationType().getSimpleName() + 
                " 是否文档化: " + isDocumented);
        }
        
        // 反射获取注解信息
        System.out.println("\n3. 反射获取注解详细信息:");
        try {
            Method method = ParentClass.class.getMethod("method", String.class);
            
            // 方法上的注解
            System.out.println("方法注解:");
            for (Annotation ann : method.getAnnotations()) {
                System.out.println("  - " + ann.annotationType().getSimpleName());
                if (ann instanceof DocumentedAnnotation) {
                    System.out.println("    值: " + ((DocumentedAnnotation) ann).value());
                }
            }
            
            // 参数上的注解
            System.out.println("参数注解:");
            Parameter[] parameters = method.getParameters();
            for (Parameter param : parameters) {
                for (Annotation ann : param.getAnnotations()) {
                    System.out.println("  - " + ann.annotationType().getSimpleName());
                }
            }
            
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
}

二、自定义注解实战

2.1 创建自定义注解

java 复制代码
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.time.*;
import java.util.*;

// 自定义注解实战
public class CustomAnnotations {
    
    // 1. 验证注解 - 用于字段验证
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    @interface Validate {
        int min() default 0;
        int max() default Integer.MAX_VALUE;
        boolean required() default false;
        String regex() default "";
        String message() default "验证失败";
    }
    
    // 2. 数据库映射注解 - 类似JPA
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE, ElementType.FIELD})
    @interface Entity {
        String tableName() default "";
    }
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    @interface Column {
        String name() default "";
        boolean nullable() default true;
        boolean unique() default false;
        int length() default 255;
    }
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    @interface Id {
        String strategy() default "AUTO";
    }
    
    // 3. API文档注解 - 类似Swagger
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER})
    @interface ApiOperation {
        String value();               // 操作描述
        String notes() default "";    // 详细说明
        HttpMethod method() default HttpMethod.GET;
        String[] tags() default {};
        
        enum HttpMethod {
            GET, POST, PUT, DELETE, PATCH
        }
    }
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.PARAMETER)
    @interface ApiParam {
        String name() default "";
        String description() default "";
        boolean required() default false;
        String defaultValue() default "";
    }
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @interface ApiResponse {
        int code();
        String message();
        Class<?> type() default Void.class;
    }
    
    // 4. 缓存注解 - 类似Spring Cache
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @interface Cacheable {
        String key() default "";
        long ttl() default 3600;  // 生存时间(秒)
        TimeUnit timeUnit() default TimeUnit.SECONDS;
        
        enum TimeUnit {
            SECONDS, MINUTES, HOURS, DAYS
        }
    }
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @interface CacheEvict {
        String key();
        boolean allEntries() default false;
    }
    
    // 5. 事务注解 - 类似Spring Transactional
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @interface Transactional {
        Propagation propagation() default Propagation.REQUIRED;
        Isolation isolation() default Isolation.DEFAULT;
        int timeout() default -1;
        boolean readOnly() default false;
        Class<? extends Throwable>[] rollbackFor() default {};
        
        enum Propagation {
            REQUIRED, REQUIRES_NEW, NESTED, SUPPORTS, NOT_SUPPORTED, NEVER, MANDATORY
        }
        
        enum Isolation {
            DEFAULT, READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
        }
    }
    
    // 应用示例:用户实体类
    @Entity(tableName = "users")
    class User {
        @Id(strategy = "AUTO")
        @Column(name = "user_id", nullable = false)
        private Long id;
        
        @Validate(required = true, min = 2, max = 50, 
                 regex = "^[a-zA-Z0-9_]+$", 
                 message = "用户名必须是2-50位的字母数字下划线")
        @Column(name = "username", nullable = false, unique = true, length = 50)
        private String username;
        
        @Validate(required = true, min = 6, 
                 message = "密码至少6位")
        @Column(name = "password", nullable = false, length = 100)
        private String password;
        
        @Validate(regex = "^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$", 
                 message = "邮箱格式不正确")
        @Column(name = "email", length = 100)
        private String email;
        
        @Validate(min = 0, max = 150, message = "年龄必须在0-150之间")
        @Column(name = "age")
        private Integer age;
        
        @Column(name = "created_at", nullable = false)
        private LocalDateTime createdAt;
        
        // 构造器、getter、setter省略...
        
        // 验证方法
        public List<String> validate() {
            List<String> errors = new ArrayList<>();
            Field[] fields = this.getClass().getDeclaredFields();
            
            for (Field field : fields) {
                if (field.isAnnotationPresent(Validate.class)) {
                    field.setAccessible(true);
                    Validate validate = field.getAnnotation(Validate.class);
                    
                    try {
                        Object value = field.get(this);
                        
                        // 检查必填
                        if (validate.required() && value == null) {
                            errors.add(field.getName() + ": " + validate.message());
                            continue;
                        }
                        
                        if (value == null) {
                            continue;  // 非必填字段为null,跳过其他验证
                        }
                        
                        // 字符串类型验证
                        if (value instanceof String) {
                            String strValue = (String) value;
                            
                            // 长度验证
                            if (strValue.length() < validate.min() || 
                                strValue.length() > validate.max()) {
                                errors.add(field.getName() + ": " + validate.message());
                            }
                            
                            // 正则验证
                            if (!validate.regex().isEmpty() && 
                                !strValue.matches(validate.regex())) {
                                errors.add(field.getName() + ": " + validate.message());
                            }
                        }
                        
                        // 数字类型验证
                        if (value instanceof Number) {
                            Number numValue = (Number) value;
                            if (numValue.intValue() < validate.min() || 
                                numValue.intValue() > validate.max()) {
                                errors.add(field.getName() + ": " + validate.message());
                            }
                        }
                        
                    } catch (IllegalAccessException e) {
                        errors.add("无法访问字段: " + field.getName());
                    }
                }
            }
            
            return errors;
        }
    }
    
    // 应用示例:用户服务类
    class UserService {
        
        @ApiOperation(
            value = "创建用户",
            notes = "创建新用户账户",
            method = ApiOperation.HttpMethod.POST,
            tags = {"用户管理"}
        )
        @ApiResponse(code = 200, message = "创建成功", type = User.class)
        @ApiResponse(code = 400, message = "参数错误")
        @Transactional(
            propagation = Transactional.Propagation.REQUIRED,
            isolation = Transactional.Isolation.READ_COMMITTED,
            rollbackFor = {RuntimeException.class}
        )
        public User createUser(
            @ApiParam(name = "username", description = "用户名", required = true)
            String username,
            
            @ApiParam(name = "password", description = "密码", required = true)
            String password,
            
            @ApiParam(name = "email", description = "邮箱")
            String email
        ) {
            User user = new User();
            // 设置属性...
            
            // 验证
            List<String> errors = user.validate();
            if (!errors.isEmpty()) {
                throw new IllegalArgumentException("验证失败: " + errors);
            }
            
            // 保存到数据库...
            return user;
        }
        
        @ApiOperation(value = "根据ID获取用户", tags = {"用户管理"})
        @Cacheable(key = "'user:' + #id", ttl = 300)
        public User getUserById(Long id) {
            // 模拟从数据库查询
            System.out.println("查询数据库,用户ID: " + id);
            
            User user = new User();
            // 设置属性...
            return user;
        }
        
        @ApiOperation(value = "删除用户", tags = {"用户管理"})
        @CacheEvict(key = "'user:' + #id")
        @Transactional
        public void deleteUser(Long id) {
            // 删除用户...
        }
    }
    
    // 注解处理器
    static class AnnotationProcessor {
        
        // 生成SQL建表语句
        public static String generateCreateTableSQL(Class<?> entityClass) {
            if (!entityClass.isAnnotationPresent(Entity.class)) {
                throw new IllegalArgumentException("不是实体类");
            }
            
            Entity entity = entityClass.getAnnotation(Entity.class);
            String tableName = entity.tableName();
            if (tableName.isEmpty()) {
                tableName = entityClass.getSimpleName().toLowerCase();
            }
            
            StringBuilder sql = new StringBuilder();
            sql.append("CREATE TABLE ").append(tableName).append(" (\n");
            
            List<String> columns = new ArrayList<>();
            List<String> primaryKeys = new ArrayList<>();
            
            Field[] fields = entityClass.getDeclaredFields();
            for (Field field : fields) {
                if (field.isAnnotationPresent(Column.class)) {
                    Column column = field.getAnnotation(Column.class);
                    String columnName = column.name().isEmpty() ? 
                        field.getName() : column.name();
                    
                    // 确定列类型
                    String columnType = getColumnType(field.getType());
                    
                    // 构建列定义
                    StringBuilder columnDef = new StringBuilder();
                    columnDef.append("  ").append(columnName).append(" ").append(columnType);
                    
                    if (!column.nullable()) {
                        columnDef.append(" NOT NULL");
                    }
                    
                    if (column.unique()) {
                        columnDef.append(" UNIQUE");
                    }
                    
                    if (field.isAnnotationPresent(Id.class)) {
                        Id id = field.getAnnotation(Id.class);
                        primaryKeys.add(columnName);
                        
                        if ("AUTO".equals(id.strategy())) {
                            if ("BIGINT".equals(columnType)) {
                                columnDef.append(" AUTO_INCREMENT");
                            } else if ("INTEGER".equals(columnType)) {
                                columnDef.append(" AUTOINCREMENT");
                            }
                        }
                    }
                    
                    columns.add(columnDef.toString());
                }
            }
            
            sql.append(String.join(",\n", columns));
            
            // 添加主键约束
            if (!primaryKeys.isEmpty()) {
                sql.append(",\n  PRIMARY KEY (")
                   .append(String.join(", ", primaryKeys))
                   .append(")");
            }
            
            sql.append("\n);");
            return sql.toString();
        }
        
        private static String getColumnType(Class<?> fieldType) {
            if (fieldType == String.class) {
                return "VARCHAR(255)";
            } else if (fieldType == Long.class || fieldType == long.class) {
                return "BIGINT";
            } else if (fieldType == Integer.class || fieldType == int.class) {
                return "INTEGER";
            } else if (fieldType == Double.class || fieldType == double.class) {
                return "DOUBLE";
            } else if (fieldType == Float.class || fieldType == float.class) {
                return "FLOAT";
            } else if (fieldType == Boolean.class || fieldType == boolean.class) {
                return "BOOLEAN";
            } else if (fieldType == LocalDateTime.class) {
                return "TIMESTAMP";
            } else if (fieldType == Date.class) {
                return "DATETIME";
            }
            return "TEXT";
        }
        
        // 生成API文档
        public static String generateApiDocumentation(Class<?> serviceClass) {
            StringBuilder doc = new StringBuilder();
            doc.append("# API文档\n\n");
            
            Method[] methods = serviceClass.getDeclaredMethods();
            for (Method method : methods) {
                if (method.isAnnotationPresent(ApiOperation.class)) {
                    ApiOperation operation = method.getAnnotation(ApiOperation.class);
                    
                    doc.append("## ").append(operation.value()).append("\n\n");
                    doc.append("**方法**: ").append(operation.method()).append("\n\n");
                    
                    if (!operation.notes().isEmpty()) {
                        doc.append("**描述**: ").append(operation.notes()).append("\n\n");
                    }
                    
                    if (operation.tags().length > 0) {
                        doc.append("**标签**: ").append(String.join(", ", operation.tags())).append("\n\n");
                    }
                    
                    // 参数
                    Parameter[] parameters = method.getParameters();
                    if (parameters.length > 0) {
                        doc.append("### 参数\n\n");
                        doc.append("| 参数名 | 描述 | 必填 | 默认值 |\n");
                        doc.append("|--------|------|------|--------|\n");
                        
                        for (Parameter param : parameters) {
                            if (param.isAnnotationPresent(ApiParam.class)) {
                                ApiParam apiParam = param.getAnnotation(ApiParam.class);
                                String paramName = apiParam.name().isEmpty() ? 
                                    param.getName() : apiParam.name();
                                
                                doc.append("| ").append(paramName)
                                   .append(" | ").append(apiParam.description())
                                   .append(" | ").append(apiParam.required() ? "是" : "否")
                                   .append(" | ").append(apiParam.defaultValue())
                                   .append(" |\n");
                            }
                        }
                        doc.append("\n");
                    }
                    
                    // 响应
                    ApiResponse[] responses = method.getAnnotationsByType(ApiResponse.class);
                    if (responses.length > 0) {
                        doc.append("### 响应\n\n");
                        doc.append("| 状态码 | 描述 | 数据类型 |\n");
                        doc.append("|--------|------|----------|\n");
                        
                        for (ApiResponse response : responses) {
                            doc.append("| ").append(response.code())
                               .append(" | ").append(response.message())
                               .append(" | ").append(response.type().getSimpleName())
                               .append(" |\n");
                        }
                        doc.append("\n");
                    }
                }
            }
            
            return doc.toString();
        }
    }
    
    public static void main(String[] args) {
        System.out.println("=== 自定义注解实战 ===\n");
        
        // 1. 生成建表SQL
        System.out.println("1. 生成User实体建表SQL:");
        try {
            String createTableSQL = AnnotationProcessor.generateCreateTableSQL(User.class);
            System.out.println(createTableSQL);
        } catch (IllegalArgumentException e) {
            System.err.println(e.getMessage());
        }
        
        System.out.println("\n2. 生成API文档:");
        String apiDoc = AnnotationProcessor.generateApiDocumentation(UserService.class);
        System.out.println(apiDoc);
        
        System.out.println("3. 验证注解演示:");
        User user = new User();
        // 设置非法数据...
        // List<String> errors = user.validate();
        // System.out.println("验证错误: " + errors);
    }
}

三、注解处理器(APT)

3.1 编译时注解处理器

java 复制代码
import javax.annotation.processing.*;
import javax.lang.model.*;
import javax.lang.model.element.*;
import javax.tools.*;
import java.io.*;
import java.util.*;
import java.util.stream.*;

/**
 * 编译时注解处理器示例
 * 需要配置:
 * 1. 创建META-INF/services/javax.annotation.processing.Processor文件
 * 2. 文件内容:com.example.MyAnnotationProcessor
 * 3. 使用javac -processor com.example.MyAnnotationProcessor编译
 */
@SupportedAnnotationTypes("com.example.*")
@SupportedSourceVersion(SourceVersion.RELEASE_11)
public class AnnotationProcessorExample extends AbstractProcessor {
    
    private Filer filer;
    private Messager messager;
    private Elements elementUtils;
    
    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        filer = processingEnv.getFiler();
        messager = processingEnv.getMessager();
        elementUtils = processingEnv.getElementUtils();
        
        messager.printMessage(Diagnostic.Kind.NOTE, "注解处理器初始化完成");
    }
    
    @Override
    public boolean process(Set<? extends TypeElement> annotations, 
                          RoundEnvironment roundEnv) {
        
        // 处理Builder注解
        for (Element element : roundEnv.getElementsAnnotatedWith(Builder.class)) {
            if (element.getKind() == ElementKind.CLASS) {
                generateBuilderClass((TypeElement) element);
            }
        }
        
        // 处理Singleton注解
        for (Element element : roundEnv.getElementsAnnotatedWith(Singleton.class)) {
            if (element.getKind() == ElementKind.CLASS) {
                generateSingletonCode((TypeElement) element);
            }
        }
        
        return true;
    }
    
    // 定义Builder注解
    @Retention(RetentionPolicy.SOURCE)  // 仅源码级别
    @Target(ElementType.TYPE)
    @interface Builder {
        String builderClassName() default "";
    }
    
    // 定义Singleton注解
    @Retention(RetentionPolicy.SOURCE)
    @Target(ElementType.TYPE)
    @interface Singleton {
        String instanceName() default "INSTANCE";
    }
    
    // 示例:被注解的类
    @Builder(builderClassName = "PersonBuilder")
    class Person {
        private String name;
        private int age;
        
        // 需要无参构造器
        public Person() {}
        
        // getters and setters...
        public void setName(String name) { this.name = name; }
        public void setAge(int age) { this.age = age; }
    }
    
    @Singleton(instanceName = "LOGGER")
    class Logger {
        public void log(String message) {
            System.out.println(message);
        }
    }
    
    // 生成Builder类
    private void generateBuilderClass(TypeElement classElement) {
        Builder builderAnnotation = classElement.getAnnotation(Builder.class);
        String className = classElement.getSimpleName().toString();
        String builderClassName = builderAnnotation.builderClassName().isEmpty() ? 
            className + "Builder" : builderAnnotation.builderClassName();
        
        String packageName = elementUtils.getPackageOf(classElement).toString();
        
        try {
            JavaFileObject builderFile = filer.createSourceFile(
                packageName + "." + builderClassName, classElement);
            
            try (PrintWriter writer = new PrintWriter(builderFile.openWriter())) {
                // 生成包声明
                writer.println("package " + packageName + ";");
                writer.println();
                writer.println("// 自动生成的Builder类");
                writer.println("// 不要手动修改此文件");
                writer.println();
                writer.println("public class " + builderClassName + " {");
                writer.println();
                
                // 生成目标类实例
                writer.println("    private " + className + " instance = new " + className + "();");
                writer.println();
                
                // 为每个setter方法生成builder方法
                List<ExecutableElement> setters = getSetterMethods(classElement);
                for (ExecutableElement setter : setters) {
                    String methodName = setter.getSimpleName().toString();
                    String fieldName = methodName.substring(3); // 去掉"set"
                    fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
                    
                    VariableElement param = setter.getParameters().get(0);
                    String paramType = param.asType().toString();
                    String paramName = param.getSimpleName().toString();
                    
                    writer.println("    public " + builderClassName + " " + fieldName + 
                                  "(" + paramType + " " + paramName + ") {");
                    writer.println("        instance." + methodName + "(" + paramName + ");");
                    writer.println("        return this;");
                    writer.println("    }");
                    writer.println();
                }
                
                // 生成build方法
                writer.println("    public " + className + " build() {");
                writer.println("        return instance;");
                writer.println("    }");
                writer.println("}");
            }
            
            messager.printMessage(Diagnostic.Kind.NOTE, 
                "生成Builder类: " + builderClassName);
            
        } catch (IOException e) {
            messager.printMessage(Diagnostic.Kind.ERROR, 
                "无法生成Builder类: " + e.getMessage());
        }
    }
    
    // 生成单例代码
    private void generateSingletonCode(TypeElement classElement) {
        Singleton singletonAnnotation = classElement.getAnnotation(Singleton.class);
        String className = classElement.getSimpleName().toString();
        String instanceName = singletonAnnotation.instanceName();
        
        String packageName = elementUtils.getPackageOf(classElement).toString();
        
        try {
            JavaFileObject singletonFile = filer.createSourceFile(
                packageName + "." + className + "Singleton", classElement);
            
            try (PrintWriter writer = new PrintWriter(singletonFile.openWriter())) {
                writer.println("package " + packageName + ";");
                writer.println();
                writer.println("// 自动生成的Singleton包装类");
                writer.println();
                writer.println("public class " + className + "Singleton {");
                writer.println();
                writer.println("    private static final " + className + 
                             " " + instanceName + " = new " + className + "();");
                writer.println();
                writer.println("    private " + className + "Singleton() {}");
                writer.println();
                writer.println("    public static " + className + " getInstance() {");
                writer.println("        return " + instanceName + ";");
                writer.println("    }");
                writer.println("}");
            }
            
            messager.printMessage(Diagnostic.Kind.NOTE,
                "生成Singleton包装类: " + className + "Singleton");
            
        } catch (IOException e) {
            messager.printMessage(Diagnostic.Kind.ERROR,
                "无法生成Singleton类: " + e.getMessage());
        }
    }
    
    // 获取所有setter方法
    private List<ExecutableElement> getSetterMethods(TypeElement classElement) {
        return ElementFilter.methodsIn(classElement.getEnclosedElements())
            .stream()
            .filter(method -> method.getSimpleName().toString().startsWith("set"))
            .filter(method -> method.getParameters().size() == 1)
            .filter(method -> method.getReturnType().toString().equals("void"))
            .collect(Collectors.toList());
    }
    
    // 手动编译测试(不使用APT)
    public static void testWithoutAPT() {
        System.out.println("=== 注解处理器模拟演示 ===");
        
        // 模拟生成的Builder类
        System.out.println("\n1. 模拟生成的PersonBuilder:");
        System.out.println("""
            public class PersonBuilder {
                private Person instance = new Person();
                
                public PersonBuilder name(String name) {
                    instance.setName(name);
                    return this;
                }
                
                public PersonBuilder age(int age) {
                    instance.setAge(age);
                    return this;
                }
                
                public Person build() {
                    return instance;
                }
            }
            """);
        
        // 模拟使用
        System.out.println("\n2. Builder使用示例:");
        System.out.println("""
            Person person = new PersonBuilder()
                .name("张三")
                .age(25)
                .build();
            """);
        
        // 模拟生成的Singleton类
        System.out.println("\n3. 模拟生成的LoggerSingleton:");
        System.out.println("""
            public class LoggerSingleton {
                private static final Logger LOGGER = new Logger();
                
                private LoggerSingleton() {}
                
                public static Logger getInstance() {
                    return LOGGER;
                }
            }
            """);
    }
    
    public static void main(String[] args) {
        testWithoutAPT();
    }
}

四、运行时注解处理框架

4.1 自定义依赖注入框架

java 复制代码
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.*;

// 自定义简单的IoC容器
public class SimpleIoCContainer {
    
    // 定义注解
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE, ElementType.FIELD})
    @interface Component {
        String value() default "";
        Scope scope() default Scope.SINGLETON;
        
        enum Scope {
            SINGLETON, PROTOTYPE
        }
    }
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    @interface Autowired {
        String name() default "";
        boolean required() default true;
    }
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @interface PostConstruct {}
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @interface Configuration {}
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @interface Bean {
        String name() default "";
        Scope scope() default Scope.SINGLETON;
    }
    
    // IoC容器实现
    static class Container {
        private final Map<String, Object> singletons = new ConcurrentHashMap<>();
        private final Map<String, Class<?>> beanDefinitions = new ConcurrentHashMap<>();
        private final Map<String, BeanInfo> beanInfoMap = new ConcurrentHashMap<>();
        
        static class BeanInfo {
            Class<?> beanClass;
            Component.Scope scope;
            String name;
            Method factoryMethod;
            Object configInstance;
            
            BeanInfo(Class<?> beanClass, Component.Scope scope, String name) {
                this.beanClass = beanClass;
                this.scope = scope;
                this.name = name;
            }
        }
        
        public void scanPackage(String basePackage) throws Exception {
            // 简化版:手动注册,实际应该扫描类路径
            System.out.println("扫描包: " + basePackage);
        }
        
        public void register(Class<?> clazz) {
            if (clazz.isAnnotationPresent(Component.class)) {
                Component component = clazz.getAnnotation(Component.class);
                String beanName = component.value().isEmpty() ? 
                    getBeanName(clazz) : component.value();
                
                BeanInfo beanInfo = new BeanInfo(
                    clazz, component.scope(), beanName
                );
                beanInfoMap.put(beanName, beanInfo);
                beanDefinitions.put(beanName, clazz);
                
                System.out.println("注册组件: " + beanName + " -> " + clazz.getName());
            }
        }
        
        public void registerConfiguration(Class<?> configClass) throws Exception {
            if (!configClass.isAnnotationPresent(Configuration.class)) {
                return;
            }
            
            Object configInstance = configClass.getDeclaredConstructor().newInstance();
            
            for (Method method : configClass.getDeclaredMethods()) {
                if (method.isAnnotationPresent(Bean.class)) {
                    Bean bean = method.getAnnotation(Bean.class);
                    String beanName = bean.name().isEmpty() ? 
                        getBeanName(method.getReturnType()) : bean.name();
                    
                    BeanInfo beanInfo = new BeanInfo(
                        method.getReturnType(), bean.scope(), beanName
                    );
                    beanInfo.factoryMethod = method;
                    beanInfo.configInstance = configInstance;
                    
                    beanInfoMap.put(beanName, beanInfo);
                    
                    System.out.println("注册Bean: " + beanName + " -> " + 
                        method.getReturnType().getName());
                }
            }
        }
        
        @SuppressWarnings("unchecked")
        public <T> T getBean(String name) throws Exception {
            // 先从单例池获取
            if (singletons.containsKey(name)) {
                return (T) singletons.get(name);
            }
            
            BeanInfo beanInfo = beanInfoMap.get(name);
            if (beanInfo == null) {
                throw new RuntimeException("Bean未找到: " + name);
            }
            
            // 创建Bean实例
            Object bean;
            if (beanInfo.factoryMethod != null) {
                // 工厂方法创建
                bean = beanInfo.factoryMethod.invoke(beanInfo.configInstance);
            } else {
                // 构造器创建
                bean = beanInfo.beanClass.getDeclaredConstructor().newInstance();
            }
            
            // 依赖注入
            injectDependencies(bean);
            
            // 调用初始化方法
            invokePostConstruct(bean);
            
            // 根据Scope处理
            if (beanInfo.scope == Component.Scope.SINGLETON) {
                singletons.put(name, bean);
            }
            
            return (T) bean;
        }
        
        public <T> T getBean(Class<T> clazz) throws Exception {
            String beanName = getBeanName(clazz);
            return getBean(beanName);
        }
        
        private void injectDependencies(Object bean) throws Exception {
            Class<?> clazz = bean.getClass();
            
            for (Field field : clazz.getDeclaredFields()) {
                if (field.isAnnotationPresent(Autowired.class)) {
                    Autowired autowired = field.getAnnotation(Autowired.class);
                    String dependencyName = autowired.name().isEmpty() ? 
                        getBeanName(field.getType()) : autowired.name();
                    
                    Object dependency = getBean(dependencyName);
                    
                    field.setAccessible(true);
                    field.set(bean, dependency);
                    
                    System.out.println("注入依赖: " + clazz.getSimpleName() + 
                        "." + field.getName() + " -> " + dependencyName);
                }
            }
        }
        
        private void invokePostConstruct(Object bean) throws Exception {
            Class<?> clazz = bean.getClass();
            
            for (Method method : clazz.getDeclaredMethods()) {
                if (method.isAnnotationPresent(PostConstruct.class)) {
                    method.setAccessible(true);
                    method.invoke(bean);
                    
                    System.out.println("调用初始化方法: " + 
                        clazz.getSimpleName() + "." + method.getName());
                }
            }
        }
        
        private String getBeanName(Class<?> clazz) {
            String className = clazz.getSimpleName();
            return className.substring(0, 1).toLowerCase() + className.substring(1);
        }
    }
    
    // 使用示例
    // 定义服务接口
    interface UserService {
        String getUserInfo(Long userId);
    }
    
    interface OrderService {
        String getOrderInfo(Long orderId);
    }
    
    interface EmailService {
        void sendEmail(String to, String content);
    }
    
    // 实现类
    @Component("userService")
    class UserServiceImpl implements UserService {
        @Autowired
        private EmailService emailService;
        
        @Override
        public String getUserInfo(Long userId) {
            emailService.sendEmail("user@example.com", "查询用户信息");
            return "用户信息: ID=" + userId;
        }
        
        @PostConstruct
        public void init() {
            System.out.println("UserService初始化完成");
        }
    }
    
    @Component(scope = Component.Scope.PROTOTYPE)
    class OrderServiceImpl implements OrderService {
        @Autowired(required = false)  // 非必需依赖
        private UserService userService;
        
        @Override
        public String getOrderInfo(Long orderId) {
            if (userService != null) {
                userService.getUserInfo(1L);
            }
            return "订单信息: ID=" + orderId;
        }
    }
    
    @Component
    class EmailServiceImpl implements EmailService {
        @Override
        public void sendEmail(String to, String content) {
            System.out.println("发送邮件到 " + to + ": " + content);
        }
    }
    
    // 配置类
    @Configuration
    class AppConfig {
        @Bean(name = "configBean")
        public String configString() {
            return "配置的字符串Bean";
        }
        
        @Bean(scope = Bean.Scope.PROTOTYPE)
        public Date currentDate() {
            return new Date();
        }
    }
    
    // 使用容器
    public static void main(String[] args) throws Exception {
        System.out.println("=== 自定义IoC容器演示 ===\n");
        
        Container container = new Container();
        
        // 注册组件
        container.register(UserServiceImpl.class);
        container.register(OrderServiceImpl.class);
        container.register(EmailServiceImpl.class);
        
        // 注册配置类
        container.registerConfiguration(AppConfig.class);
        
        System.out.println("\n=== 获取Bean测试 ===");
        
        // 获取单例Bean
        UserService userService = container.getBean("userService");
        System.out.println("用户服务: " + userService.getUserInfo(1L));
        
        // 获取原型Bean(每次都是新实例)
        OrderService orderService1 = container.getBean(OrderServiceImpl.class);
        OrderService orderService2 = container.getBean(OrderServiceImpl.class);
        System.out.println("订单服务实例是否相同: " + (orderService1 == orderService2));
        
        // 获取配置的Bean
        String configBean = container.getBean("configBean");
        System.out.println("配置Bean: " + configBean);
        
        Date date1 = container.getBean(Date.class);
        Date date2 = container.getBean(Date.class);
        System.out.println("Date实例是否相同: " + (date1 == date2));
        
        System.out.println("\n=== 容器状态 ===");
        System.out.println("单例池大小: " + container.singletons.size());
        System.out.println("Bean定义数量: " + container.beanInfoMap.size());
    }
}

五、注解性能与最佳实践

5.1 注解性能分析与优化

java 复制代码
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.util.concurrent.*;

public class AnnotationPerformance {
    
    // 性能测试注解
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @interface Benchmark {
        int iterations() default 1000;
        TimeUnit timeUnit() default TimeUnit.NANOSECONDS;
    }
    
    // 缓存注解信息,避免重复反射
    static class AnnotationCache {
        private static final Map<Method, Benchmark> benchmarkCache = 
            new ConcurrentHashMap<>();
        
        public static Benchmark getBenchmarkAnnotation(Method method) {
            return benchmarkCache.computeIfAbsent(method, m -> 
                m.getAnnotation(Benchmark.class));
        }
    }
    
    // 性能测试运行器
    static class BenchmarkRunner {
        public static void runBenchmarks(Object instance) throws Exception {
            Class<?> clazz = instance.getClass();
            
            for (Method method : clazz.getDeclaredMethods()) {
                Benchmark benchmark = AnnotationCache.getBenchmarkAnnotation(method);
                if (benchmark != null) {
                    runBenchmark(method, instance, benchmark);
                }
            }
        }
        
        private static void runBenchmark(Method method, Object instance, 
                                        Benchmark benchmark) throws Exception {
            int iterations = benchmark.iterations();
            TimeUnit timeUnit = benchmark.timeUnit();
            
            // 预热
            for (int i = 0; i < 10; i++) {
                method.invoke(instance);
            }
            
            // 执行基准测试
            long startTime = System.nanoTime();
            
            for (int i = 0; i < iterations; i++) {
                method.invoke(instance);
            }
            
            long endTime = System.nanoTime();
            long duration = endTime - startTime;
            
            // 转换为指定时间单位
            double convertedDuration = convertToTimeUnit(duration, timeUnit);
            
            System.out.printf("方法 %s: %d次迭代, 总耗时: %.2f %s, 平均耗时: %.4f %s%n",
                method.getName(),
                iterations,
                convertedDuration,
                timeUnit.name().toLowerCase(),
                convertedDuration / iterations,
                timeUnit.name().toLowerCase());
        }
        
        private static double convertToTimeUnit(long nanos, TimeUnit timeUnit) {
            switch (timeUnit) {
                case NANOSECONDS: return nanos;
                case MICROSECONDS: return nanos / 1000.0;
                case MILLISECONDS: return nanos / 1_000_000.0;
                case SECONDS: return nanos / 1_000_000_000.0;
                default: return nanos;
            }
        }
    }
    
    // 测试类
    static class PerformanceTest {
        
        @Benchmark(iterations = 10000)
        public void fastMethod() {
            // 快速方法
            Math.sqrt(123.456);
        }
        
        @Benchmark(iterations = 1000, timeUnit = TimeUnit.MICROSECONDS)
        public void mediumMethod() {
            // 中等速度方法
            for (int i = 0; i < 100; i++) {
                Math.pow(i, 2);
            }
        }
        
        @Benchmark(iterations = 100, timeUnit = TimeUnit.MILLISECONDS)
        public void slowMethod() {
            // 慢速方法
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        
        // 没有注解的方法,不会被测试
        public void ignoredMethod() {
            System.out.println("这个方法不会被测试");
        }
    }
    
    // 反射性能对比
    static class ReflectionPerformance {
        
        public static void comparePerformance() throws Exception {
            PerformanceTest test = new PerformanceTest();
            Method method = PerformanceTest.class.getMethod("fastMethod");
            
            int iterations = 100000;
            
            // 直接调用
            long start = System.nanoTime();
            for (int i = 0; i < iterations; i++) {
                test.fastMethod();
            }
            long directTime = System.nanoTime() - start;
            
            // 反射调用(无缓存)
            start = System.nanoTime();
            for (int i = 0; i < iterations; i++) {
                method.invoke(test);
            }
            long reflectionTime = System.nanoTime() - start;
            
            // 反射调用(设置可访问)
            method.setAccessible(true);
            start = System.nanoTime();
            for (int i = 0; i < iterations; i++) {
                method.invoke(test);
            }
            long accessibleTime = System.nanoTime() - start;
            
            System.out.println("=== 反射性能对比 ===");
            System.out.printf("直接调用: %d ns%n", directTime);
            System.out.printf("反射调用: %d ns (慢%.1f倍)%n", 
                reflectionTime, reflectionTime * 1.0 / directTime);
            System.out.printf("反射(setAccessible): %d ns (慢%.1f倍)%n", 
                accessibleTime, accessibleTime * 1.0 / directTime);
        }
    }
    
    // 注解最佳实践
    static class BestPractices {
        public static void showBestPractices() {
            System.out.println("\n=== 注解最佳实践 ===");
            
            System.out.println("\n1. 合理选择保留策略:");
            System.out.println("   • @Retention(SOURCE) - 编译时处理,不影响运行时性能");
            System.out.println("   • @Retention(CLASS) - 默认策略,生成类文件但不加载");
            System.out.println("   • @Retention(RUNTIME) - 运行时可用,但有性能开销");
            
            System.out.println("\n2. 明确指定目标:");
            System.out.println("   • 使用@Target限制注解使用位置");
            System.out.println("   • 避免过于宽泛的目标范围");
            
            System.out.println("\n3. 设计简洁的注解:");
            System.out.println("   • 提供合理的默认值");
            System.out.println("   • 避免复杂的属性类型");
            System.out.println("   • 保持注解的单一职责");
            
            System.out.println("\n4. 性能优化:");
            System.out.println("   • 缓存注解信息,避免重复反射");
            System.out.println("   • 使用编译时注解处理(APT)减少运行时开销");
            System.out.println("   • 考虑使用Annotation Inheritance减少重复注解");
            
            System.out.println("\n5. 文档和命名:");
            System.out.println("   • 为自定义注解提供详细的JavaDoc");
            System.out.println("   • 使用一致的命名规范");
            System.out.println("   • 考虑向后兼容性");
        }
    }
    
    public static void main(String[] args) throws Exception {
        System.out.println("=== 注解性能与最佳实践 ===\n");
        
        // 运行基准测试
        PerformanceTest test = new PerformanceTest();
        BenchmarkRunner.runBenchmarks(test);
        
        System.out.println();
        
        // 反射性能对比
        ReflectionPerformance.comparePerformance();
        
        // 最佳实践
        BestPractices.showBestPractices();
    }
}

总结:注解的强大与智慧

注解的核心价值:

  1. 元编程能力:在代码中添加元数据,影响编译和运行时行为
  2. 减少样板代码:通过注解处理器自动生成代码
  3. 框架集成:Spring、Hibernate等框架的核心机制
  4. 编译时检查:提供额外的编译时验证

实用建议:

  1. 优先使用内置注解:如@Override、@Deprecated、@FunctionalInterface
  2. 合理选择保留策略:避免不必要的运行时开销
  3. 考虑性能影响:反射调用比直接调用慢10-100倍
  4. 利用编译时处理:APT可以生成代码,减少运行时负担

适用场景:

  • 适合使用注解:框架扩展、代码生成、配置管理、文档生成
  • ⚠️ 谨慎使用注解:性能敏感代码、简单逻辑、过度设计
  • 避免使用注解:复杂的业务逻辑、替代设计模式
相关推荐
海南java第二人3 分钟前
SpringBoot启动流程深度解析:从入口到容器就绪的完整机制
java·开发语言
问今域中5 分钟前
Spring Boot 请求参数绑定注解
java·spring boot·后端
星火开发设计7 分钟前
C++ queue 全面解析与实战指南
java·开发语言·数据结构·c++·学习·知识·队列
rgeshfgreh9 分钟前
Java+GeoTools+PostGIS高效求解对跖点
java
鱼跃鹰飞10 分钟前
DDD中的防腐层
java·设计模式·架构
计算机程序设计小李同学12 分钟前
婚纱摄影集成管理系统小程序
java·vue.js·spring boot·后端·微信小程序·小程序
栈与堆1 小时前
LeetCode 19 - 删除链表的倒数第N个节点
java·开发语言·数据结构·python·算法·leetcode·链表
一路向北·重庆分伦1 小时前
03-01:MQ常见问题梳理
java·开发语言
一 乐1 小时前
绿色农产品销售|基于springboot + vue绿色农产品销售系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·后端·宠物
lhrimperial1 小时前
企业智能知识库助手落地实践:从RAG到Multi-Agent
java·spring cloud·微服务·系统架构·知识图谱