注解样例-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)

  1. SOURCE:仅源码存在,编译后丢弃(如@Override)
  2. CLASS:保留到class字节码,运行时JVM丢弃(默认)
  3. 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;
}

规则:

  1. @interface 定义注解;
  2. 内部声明属性,支持基本类型、String、枚举、注解、对应数组;
  3. 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

七、核心底层串联(面试必说)

  1. 注解本身只是标记,没有执行逻辑
  2. 想要让注解生效,必须通过反射在运行时获取注解信息;
  3. Spring IOC:启动扫描带@Service的类,反射实例化存入容器;
  4. Spring AOP:反射读取@Aspect、切入点表达式,通过动态代理生成增强对象;
  5. 流程闭环:注解标记 → 反射解析 → 动态代理增强 → IOC容器管理

八、常见坑点

  1. 自定义注解不加 @Retention(RetentionPolicy.RUNTIME),运行时反射获取不到;
  2. @Inherited 只对类注解生效,方法注解无法继承;
  3. 注解属性只能是常量,不能传复杂对象;
  4. 内部调用本类方法,AOP注解失效(没有走代理对象)。

极简背诵总结

  1. 注解是代码元数据,用来标记类、方法;
  2. 四个元注解控制注解生效位置与生命周期;
  3. 自定义注解配合反射才能实现业务逻辑;
  4. Spring IOC/AOP底层大量依靠注解+反射+动态代理实现。
posted @ 2026-07-17 22:38  alij  阅读(4)  评论(0)    收藏  举报