一、注解的本质:不只是注释!
注解是附加在类/方法/字段等元素上的标记接口。编译器和JVM可读取它们,实现:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DebugLog {} // 自定义注解
二、元注解:注解的指挥官
定义注解行为的基石:
@Target(ElementType.METHOD) // 作用在方法上
@Retention(RetentionPolicy.RUNTIME) // 运行时保留
public @interface RequiresRole {
String value() default "USER"; // 注解参数
}
三、实战示例:权限校验注解
1. 定义权限注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RequiresRole {
String[] roles();
}
2. 使用注解标记敏感方法
public class UserService {
@RequiresRole(roles = {"ADMIN"})
public void deleteUser(String userId) {
System.out.println("删除用户: " + userId);
}
}
3. 通过反射实现动态拦截
public class SecurityAspect {
public static void checkAccess(Object target, Method method) {
if (method.isAnnotationPresent(RequiresRole.class)) {
RequiresRole ann = method.getAnnotation(RequiresRole.class);
String[] requiredRoles = ann.roles();
// 模拟当前用户角色(实际从Session获取)
String currentRole = "USER";
if (!Arrays.asList(requiredRoles).contains(currentRole)) {
throw new SecurityException("权限不足!需角色: " + Arrays.toString(requiredRoles));
}
}
// 继续执行业务方法...
}
}
四、进阶应用:注解驱动日志
结合AOP框架(如Spring AOP):
@Aspect
@Component
public class LoggingAspect {
@Around("@annotation(com.example.DebugLog)")
public Object logExecution(ProceedingJoinPoint pjp) throws Throwable {
long start = System.currentTimeMillis();
Object result = pjp.proceed();
long duration = System.currentTimeMillis() - start;
System.out.printf("方法 %s 执行耗时: %d ms\n", pjp.getSignature(), duration);
return result;
}
}
五、注解的最佳实践
- 明确生命周期:根据用途选择
SOURCE(编译检查)、CLASS(字节码处理)、RUNTIME(运行时反射) - 避免过度设计:优先使用标准注解(如
@Override,@Deprecated) - 工具链支持:结合Lombok、MapStruct等提升开发效率
- 谨慎反射性能:RUNTIME注解的频繁反射调用可能影响性能
关键结论:Java注解将声明式编程引入语言核心。通过解耦元数据与业务逻辑,它成为Spring/Hibernate等框架的基石。掌握自定义注解与处理机制,可显著提升代码表达力与架构灵活性,但需警惕过度使用导致的复杂度提升。
317

被折叠的 条评论
为什么被折叠?



