Java注解本质是继承Annotation接口的元数据载体,不执行逻辑;其生命周期由@Retention控制(SOURCE/CLASS/RUNTIME),运行时生效需RUNTIME级别并配合反射获取;Spring等框架通过后置处理器和扫描机制解析注解实现功能。

大厂面试中,Java 注解(Annotation)不是“会不会用”的问题,而是“为什么这么设计”“底层怎么工作”“哪些场景必须用它”的深度考察。光会写 @Override 或 @Autowired 远远不够。
注解的本质:不是语法糖,是元数据载体
注解本身不执行逻辑,它是插在代码上的“标签”,供编译器、JVM 或框架读取和响应。关键要分清三类生命周期:
-
@Retention(RetentionPolicy.SOURCE):仅在源码阶段存在,如
@Override,编译后就没了 - @Retention(RetentionPolicy.CLASS):编译进 class 文件但运行时不可见,多数 Lombok 注解属此类
-
@Retention(RetentionPolicy.RUNTIME):运行期可通过反射获取,Spring 的
@Controller、MyBatis 的@Select都依赖它
手写一个运行时注解:从定义到生效
面试常让现场写一个自定义注解并解析。核心三步不能漏:
- 用
@interface定义注解,标注@Retention(RUNTIME)和@Target(比如ElementType.METHOD) - 声明属性(支持基本类型、String、Class、枚举、其他注解及它们的数组)
- 写解析逻辑:用
clazz.getDeclaredMethod(...).getAnnotation(...)获取,再根据属性值做处理(比如打印日志、校验参数)
注意:反射获取注解是开销操作,生产环境需缓存结果,别在高频方法里反复调用。
立即学习“Java免费学习笔记(深入)”;
Spring 中注解的“魔法”是怎么来的?
Spring 不是靠注解本身干活,而是靠 后置处理器(BeanPostProcessor) 和 扫描机制 配合实现的:
-
@ComponentScan触发类路径扫描,找到带@Component及其派生注解(@Service等)的类,注册为 Bean 定义 -
@Autowired由AutowiredAnnotationBeanPostProcessor在 Bean 初始化后注入依赖 -
@Transactional本质是 AOP,由InfrastructureAdvisorAutoProxyCreator创建代理对象,拦截方法加事务逻辑
所以面试被问“@Transactional 失效原因”,本质是在考你是否理解代理机制和注解的触发时机。
高频陷阱题与回答要点
这些题一答错就暴露基础漏洞:
-
“注解能继承吗?” → 默认不能。需显式加
@Inherited,且只对CLASS或RUNTIME类型 + 作用于类的注解有效 - “可以重复使用同一个注解吗?” → JDK 8 起支持,但要先定义容器注解(@Repeatable(MyAnnos.class)),再让目标注解标注该容器
-
“注解和接口有什么关系?” → 编译后注解本质是继承了
java.lang.annotation.Annotation的特殊接口,JVM 会为其生成代理实现类


















