注解样例-cnblog
Java 注解完整讲解(面试版,搭配IOC/AOP使用场景)
一、注解是什么
注解(Annotation):代码里的标记、元数据,给类、方法、变量、参数打上附加信息。
- 只存描述信息,本身不直接执行逻辑;
- 需要反射读取注解内容,再根据注解做对应处理(Spring/IOC/AOP全靠注解)。
和注释区别:
- 注释:给人看,编译后丢弃;
- 注解:给程序看,编译/运行期可通过反射解析。
二、三大内置基础注解(源码自带)
1. @Override
标记重写父类/接口方法;编译器校验:方法签名不一致直接报错。
@Override
public void run(){}
2. @Deprecated
标记已过时,调用时编译器警告。
3. @SuppressWarnings("unchecked")
压制编译器警告,如泛型未强转、未使用变量等。
三、四个元注解(用来修饰自定义注解)
元注解 = 注解的注解,定义自定义注解的生效范围、生命周期。
1. @Target
限定注解能标注在哪些位置,常用取值:
TYPE:类、接口、枚举FIELD:成员变量METHOD:方法PARAMETER:方法参数CONSTRUCTOR:构造器LOCAL_VARIABLE:局部变量
示例:@Target({ElementType.METHOD, ElementType.TYPE})
2. @Retention
注解生命周期(核心,反射解析必须 RUNTIME)
SOURCE:仅源码存在,编译后丢弃(如@Override)CLASS:保留到class字节码,运行时JVM丢弃(默认)RUNTIME:运行时保留,可通过反射读取(Spring所有注解都是这个)
3. @Documented
生成javadoc文档时,把注解信息包含进去。
4. @Inherited
可继承:子类自动拥有父类上的该注解。
四、自定义注解完整示例
1. 定义注解
import java.lang.annotation.*;
// 元注解:作用在方法/类上,运行时保留
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface LogRecord {
// 注解属性,格式:类型 名称() default 默认值
String value() default "";
int type() default 1;
}
规则:
- 用
@interface定义注解; - 内部声明属性,支持基本类型、String、枚举、注解、对应数组;
value是特殊属性,使用时可省略value=。
2. 使用注解
@LogRecord(value = "用户新增", type = 2)
public void addUser(){}
3. 反射解析注解(AOP底层逻辑)
// 获取方法
Method method = UserService.class.getMethod("addUser");
// 判断是否有该注解
if(method.isAnnotationPresent(LogRecord.class)){
// 获取注解对象
LogRecord log = method.getAnnotation(LogRecord.class);
String desc = log.value();
int type = log.type();
System.out.println(desc + " " + type);
}
Spring AOP、IOC 底层全是这套反射读取注解逻辑。
五、注解分类
1. 标记注解(无属性)
@Override、@Aspect,仅做标记,无参数。
2. 单值注解(只有value属性)
@Component("userService"),使用简便。
3. 完整注解(多个属性)
@RequestMapping(path = "/user", method = RequestMethod.GET)
六、Spring高频注解分类(结合之前IOC/AOP)
1. IOC Bean注册注解(把类交给容器管理)
@Component:通用Bean@Service:业务层@Repository:持久层DAO@Controller:控制层
原理:Spring启动扫描包,反射读取注解,自动创建对象存入IOC容器。
2. 依赖注入注解 DI
@Autowired:按类型注入@Qualifier("beanName"):配合Autowired按名称匹配@Value("${config.key}"):读取配置文件
3. AOP相关注解
@Aspect:标记切面类@Before @Around @After:各类通知@Pointcut:定义切入点
4. 事务注解
@Transactional:方法加注解,AOP动态代理拦截实现事务。
5. Web注解
@RequestMapping、@GetMapping、@PostMapping
七、核心底层串联(面试必说)
- 注解本身只是标记,没有执行逻辑;
- 想要让注解生效,必须通过反射在运行时获取注解信息;
- Spring IOC:启动扫描带
@Service的类,反射实例化存入容器; - Spring AOP:反射读取
@Aspect、切入点表达式,通过动态代理生成增强对象; - 流程闭环:注解标记 → 反射解析 → 动态代理增强 → IOC容器管理。
八、常见坑点
- 自定义注解不加
@Retention(RetentionPolicy.RUNTIME),运行时反射获取不到; @Inherited只对类注解生效,方法注解无法继承;- 注解属性只能是常量,不能传复杂对象;
- 内部调用本类方法,AOP注解失效(没有走代理对象)。
极简背诵总结
- 注解是代码元数据,用来标记类、方法;
- 四个元注解控制注解生效位置与生命周期;
- 自定义注解配合反射才能实现业务逻辑;
- Spring IOC/AOP底层大量依靠注解+反射+动态代理实现。

浙公网安备 33010602011771号