注解应用场景
注解的真正威力在于框架和应用层的结合。Spring、Hibernate、JUnit 等框架都大量使用注解来实现「配置即代码」。
典型应用场景
| 场景 | 框架示例 | 作用 |
|---|---|---|
| 配置管理 | Spring @Configuration | 替代 XML 配置 |
| 依赖注入 | Spring @Autowired | 自动注入 Bean |
| 请求映射 | Spring @GetMapping | 绑定 URL 到方法 |
| 参数校验 | Hibernate @NotNull | 运行时数据校验 |
| 对象映射 | MyBatis @Select | SQL 与方法绑定 |
| 测试标记 | 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 │
└─────────────┴────────────────────────────────────────────┘注意事项
- 注解不能执行逻辑:注解本身只是标记,需要配合反射或 AOP 处理
- 运行时注解需要 Retention(RUNTIME):编译时处理则用 SOURCE 或 CLASS
- 框架集成:Spring 等框架在启动时扫描注解,完成 Bean 注册和依赖注入
- 性能考虑:大量使用反射解析注解有开销,Spring 用了缓存优化
