Java运行时注解需用@Retention(RetentionPolicy.RUNTIME)声明,核心步骤:定义注解→使用注解→反射读取→结合代理/AOP执行逻辑。

Java 中运行时注解需配合 @Retention(RetentionPolicy.RUNTIME) 声明,才能在程序运行期通过反射读取。核心步骤是:定义注解 → 在类/方法上使用 → 用反射获取注解实例 → 根据注解值触发对应逻辑。
1. 正确定义运行时注解
必须指定 RetentionPolicy.RUNTIME,并明确作用目标(如方法、类):
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecution {
String value() default "default";
boolean enabled() default true;
}注意:@Documented 和 @Inherited 非必需,按需添加。
2. 在目标元素上使用注解
可标注在类或方法上,便于后续反射扫描:
立即学习“Java免费学习笔记(深入)”;
@LogExecution(value = "UserService", enabled = true)
public class UserService {
<pre class="brush:php;toolbar:false;">@LogExecution(value = "createUser", enabled = true)
public void createUser(String name) {
System.out.println("Creating user: " + name);
}}
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
3. 用反射读取并处理注解
通过 Class.getAnnotation() 或 Method.getAnnotation() 获取注解对象,再根据其属性执行逻辑:
- 检查类是否带有注解:
clazz.isAnnotationPresent(LogExecution.class) - 获取类级注解:
clazz.getAnnotation(LogExecution.class) - 遍历所有方法,获取方法级注解:
method.getAnnotation(LogExecution.class) - 调用注解方法获取配置值,例如:
logAnn.value()、logAnn.enabled()
示例逻辑(打印带注解的方法名及配置):
public static void processLogAnnotations(Class<?> clazz) {
LogExecution classAnn = clazz.getAnnotation(LogExecution.class);
if (classAnn != null && classAnn.enabled()) {
System.out.println("Class level: " + classAnn.value());
}
<pre class="brush:php;toolbar:false;">for (Method method : clazz.getDeclaredMethods()) {
LogExecution methodAnn = method.getAnnotation(LogExecution.class);
if (methodAnn != null && methodAnn.enabled()) {
System.out.println("Method [" + method.getName() + "] -> " + methodAnn.value());
}
}}
4. 结合动态代理或 AOP 实现自动执行
单纯反射读取只是“发现”,真正“执行逻辑”常需拦截调用。常见做法:
- 手动在关键入口调用解析方法(适合简单场景)
- 用 JDK 动态代理包装目标对象,在
invoke()中检查被调用方法是否有注解,有则先执行日志/校验等逻辑 - 集成 Spring AOP:写一个
@Aspect切面,使用@Around("@annotation(logExecution)")拦截带该注解的方法
Spring AOP 示例片段:
@Aspect
@Component
public class LogExecutionAspect {
@Around("@annotation(logAnn)")
public Object logExecutionTime(ProceedingJoinPoint joinPoint, LogExecution logAnn) throws Throwable {
long start = System.currentTimeMillis();
Object result = joinPoint.proceed();
long duration = System.currentTimeMillis() - start;
System.out.printf("[%s] executed in %d ms%n", logAnn.value(), duration);
return result;
}
}这样,只要方法标了 @LogExecution,就自动记录执行耗时,无需侵入业务代码。

















