Skip to content

注解应用场景

注解的真正威力在于框架和应用层的结合。Spring、Hibernate、JUnit 等框架都大量使用注解来实现「配置即代码」。

典型应用场景

场景框架示例作用
配置管理Spring @Configuration替代 XML 配置
依赖注入Spring @Autowired自动注入 Bean
请求映射Spring @GetMapping绑定 URL 到方法
参数校验Hibernate @NotNull运行时数据校验
对象映射MyBatis @SelectSQL 与方法绑定
测试标记JUnit @Test标记测试方法

代码示例

配置注解

模拟 Spring 的 @Configuration

java
import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface Configuration {
    String value() default "";
}

@Configuration("database")
class DatabaseConfig {
    public String getUrl() {
        return "jdbc:mysql://localhost:3306";
    }
}

依赖注入注解

模拟 Spring 的 @Autowired

java
import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.CONSTRUCTOR})
@interface Inject {}

class Repository {}
class Service {}

class UserService {
    @Inject
    private Repository repository;  // 自动注入
}

public class InjectionDemo {

    public static <T> T inject(T obj) throws Exception {
        for (Field field : obj.getClass().getDeclaredFields()) {
            if (field.isAnnotationPresent(Inject.class)) {
                field.setAccessible(true);
                field.set(obj, field.getType().getDeclaredConstructor().newInstance());
                System.out.println("Injected: " + field.getName());
            }
        }
        return obj;
    }

    public static void main(String[] args) throws Exception {
        UserService service = new UserService();
        inject(service);
        System.out.println("Repository: " + service.repository);
    }
}

参数校验注解

java
import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
@interface NotNull {}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
@interface Min {
    int value();
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
@interface Max {
    int value();
}

class Validator {

    public static void validate(Object... args) {
        System.out.println("Validating parameters...");
    }
}

class UserService {
    public void createUser(
            @NotNull String username,
            @Min(0) int age,
            @Max(100) int score) {
        System.out.println("Creating user: " + username + ", age: " + age);
    }
}

日志注解

AOP(面向切面编程)的典型应用:

java
import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface Log {
    String value() default "info";
}

class BusinessService {

    @Log("debug")
    public void processOrder() {
        System.out.println("Processing order...");
    }

    @Log("error")
    public void handleError() {
        System.out.println("Handling error...");
    }
}

public class LogAspect {

    public static void main(String[] args) throws Exception {
        for (Method method : BusinessService.class.getDeclaredMethods()) {
            if (method.isAnnotationPresent(Log.class)) {
                Log log = method.getAnnotation(Log.class);
                System.out.println("Method: " + method.getName() +
                    " -> Log level: " + log.value());
            }
        }
    }
}

ORM 映射注解

模拟 MyBatis/Hibernate 的字段映射:

java
import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface Table {
    String name();
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface Column {
    String name();
    String type() default "VARCHAR";
    int length() default 255;
}

@Table(name = "t_user")
class User {
    @Column(name = "id", type = "INT")
    private int id;

    @Column(name = "username", length = 50)
    private String username;

    @Column(name = "email")
    private String email;
}

public class OrmDemo {

    public static void main(String[] args) {
        if (User.class.isAnnotationPresent(Table.class)) {
            Table table = User.class.getAnnotation(Table.class);
            System.out.println("Table: " + table.name());

            System.out.println("Columns:");
            for (Field field : User.class.getDeclaredFields()) {
                if (field.isAnnotationPresent(Column.class)) {
                    Column column = field.getAnnotation(Column.class);
                    System.out.printf("  %s %s(%d)%n",
                        column.type(), column.name(), column.length());
                }
            }
        }
    }
}

Spring 常用注解速查

┌─────────────────────────────────────────────────────────┐
│                    Spring 常用注解                         │
├─────────────┬────────────────────────────────────────────┤
│  分层       │ @Controller  @Service  @Repository        │
│  注入       │ @Autowired  @Qualifier  @Resource          │
│  配置       │ @Configuration  @Bean  @Value             │
│  事务       │ @Transactional                            │
│  Web        │ @RequestMapping  @GetMapping  @PostMapping│
│  参数       │ @RequestParam  @RequestBody  @PathVariable │
└─────────────┴────────────────────────────────────────────┘

注意事项

  1. 注解不能执行逻辑:注解本身只是标记,需要配合反射或 AOP 处理
  2. 运行时注解需要 Retention(RUNTIME):编译时处理则用 SOURCE 或 CLASS
  3. 框架集成:Spring 等框架在启动时扫描注解,完成 Bean 注册和依赖注入
  4. 性能考虑:大量使用反射解析注解有开销,Spring 用了缓存优化

基于 VitePress 构建