JAVA中的常用注解
JAVA中的常用注解
1. JAVA自带
1.1 @Override
用来标识当前方法是重写父类或接口中的方法
1 | |
- 写在方法上
- 重写父类方法/实现接口方法
1.2 @Serial
避免序列化相关方法“写错签名”
1 | |
2. Spring / Spring Boot / Spring Cloud核心注解
2.1 Spring Boot 核心注解
- @SpringBootApplication: 用于标注SpringBoot主启动类: 等同于
@EnableAutoConfiguration+@ComponentScan+@Configuration - @EnableAutoConfiguration: 启用 Spring Boot 的自动配置机制
- @ComponentScan: 扫描 @Component、@Service、@Repository、@Controller 等注解的类
- @Configuration: 用于告诉Spring:这个类是一个配置类,可以向 Spring容器注册Bean
- @Bean: @Bean让你可以手动创建对象并交给 Spring容器管理
- @Conditional: 只有当指定条件满足时,Spring 才会创建这个 Bean;否则此 Bean 不会加载进入容器
2.1.1 @SpringBootApplication
是 Spring Boot 应用的核心注解,通常用于标注主启动类
1 | |
我们可以把 @SpringBootApplication看作是下面三个注解的组合:
@EnableAutoConfiguration:启用 Spring Boot 的自动配置机制。@ComponentScan:扫描 @Component、@Service、@Repository、@Controller 等注解的类。@Configuration:允许注册额外的 Spring Bean 或导入其他配置类。
2.1.2 @EnableAutoConfiguration
启用 Spring Boot 的自动配置机制
2.1.3 @ComponentScan
指定 Spring 要扫描哪些包,从而把标注了 @Component、@Service、@Controller、@Repository 等注解的类自动注册为 Bean
在 Spring 中,只要类上有:
@Component@Service@Controller@RestController@Repository@Configuration
这些注解,Spring 才会将它们加载进 IOC 容器。
但是:
⭐ Spring 默认只扫描启动类所在包及其子包
⭐ 想让 Spring 扫描其他路径,就要用 @ComponentScan
2.1.4 @Configuration
用于告诉 Spring:这个类是一个配置类,可以向 Spring 容器注册 Bean
- 声明当前类为 Spring 配置类
- Spring 启动时会将这个类当成配置源,解析并注册 Bean。
- 启用 @Bean 方法
- 在配置类中,任何使用 @Bean 的方法都会创建一个 Bean 并加入 IOC 容器。
1 | |
2.1.5 @Bean
是 Spring 提供的注解,用于把方法的返回值注册成 Spring 容器中的一个 Bean。
- @Bean = 手动创建一个 Bean 并交给 Spring 管理
最常见的使用方式:
1 | |
上面的 userService() 返回的对象就会被 Spring 容器管理。
你可以这样注入它:
1 | |
2.1.6 @Conditional
条件化配置: 只有当指定条件满足时,Spring 才会创建这个 Bean;否则此 Bean 不会加载进入容器。
2.2 Bean注册注解
Spring 容器需要知道哪些类需要被管理为 Bean,以下注解注解在类上,可以让 Spring 自动发现并注册这些类作为 Bean对象。
@Component:通用的注解,可标注任意类为 Spring 组件@Repository: 对应持久层即 Dao 层,主要用于数据库相关操作@Service: 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao 层@Controller: 对应 Spring MVC 控制层,主要用于接受用户请求并调用 Service 层返回数据给前端页面@RestController:一个组合注解,等效于 @Controller + @ResponseBody,返回 JSON 的控制器
除此之外,还可以通过使用@Configuration + @Bean方法显式声明(通常在 @Configuration 类中)
1 | |
2.3 依赖注入(DI)注解
- @Autowired: 按类型自动注入Bean
- @Qualifier: 指定注入 Bean 的名称
- @Resource: 按名称优先注入
- @Value: 注入配置文件中的属性
- @Lazy: 延迟加载 Bean
- @Primary: 默认 Bean,优先注入
- @Scope:设置 Bean 的作用域
2.3.1 @Autowired
- Spring 根据 类型(byType) 自动找到对应的 Bean 并注入。
- 常用于 Service 层、Controller 层注入依赖。
1 | |
自动找到 UserService 并注入
2.3.2 @Qualifier
当有多个同类型 Bean 时,用来 精确指定注入哪一个
1 | |
避免类型冲突,精确注入。
2.3.3 @Resource
默认按名称注入,找不到再按类型
1 | |
2.3.4 @Value
从 application.yml / properties 中取值并注入到字段中。
- 常用于:读取配置、注入常量
1 | |
Java 注入:
1 | |
2.3.5 @Lazy
- 让 Spring 在 第一次使用这个 Bean 时再创建它,而不是启动时创建。
- 可以节省内存或加快启动速度。
1 | |
控制类
1 | |
2.3.6 @Primary
当有多个 Bean 同类型时,设置某一个为 默认首选。
1 | |
避免每次都写 @Qualifier
2.3.7 @Scope
设置 Bean 的作用域
| scope | 含义 |
|---|---|
| singleton | 单例(默认) |
| prototype | 每次注入或获取都创建新实例 |
| request | 每个 HTTP 请求创建一个(Web) |
| session | 每个 Session 一个(Web) |
1 | |
使用:
1 | |
2.4 Spring MVC(Web 层)注解
- @RequestMapping: 请求路径映射
- @GetMapping: GET 请求映射
- @PostMapping: POST 请求映射
- @PutMapping: PUT 请求映射
- @DeleteMapping: DELETE 请求映射
- @RequestBody: 接收 JSON 请求体
- @RequestParam: 接收 URL 或表单参数
- @PathVariable: 接收路径参数
- @ResponseBody: 返回 JSON 内容
2.4.1 @RequestMapping
- 为类或方法提供 URL 路径映射
- 可用于所有请求方式(GET/POST/PUT/DELETE)
1 | |
访问路径:
1 | |
2.4.2 @GetMapping/@PostMapping/@PutMapping/@DeleteMapping
- GET:请求从服务器获取特定资源。举个例子:GET /users(获取所有学生)
- POST:在服务器上创建一个新的资源。举个例子:POST /users(创建学生)
- PUT:更新服务器上的资源(客户端提供更新后的整个资源)。举个例子:PUT /users/12(更新编号为 12 的学生)
- DELETE:从服务器删除特定的资源。举个例子:DELETE /users/12(删除编号为 12 的学生)
1 | |
2.4.3 @RequestBody
- 将JSON数据转成Java对象
- 常用于 POST、PUT 请求
1 | |
发送 JSON:
1 | |
2.4.4 @RequestParam
接收如下格式的参数:
1 | |
1 | |
2.4.5 @PathVariable
通过 URL 上的动态占位符获取参数
1 | |
1 | |
2.4.6 @ResponseBody
将方法返回的对象自动序列化为 JSON
1 | |
2.5 AOP(切面编程)注解
@Aspect: 声明一个切面类@Pointcut: 定义切点, 表示“哪些方法需要被拦截”
Spring中AOP的通知类型:
@Around:环绕通知,此注解标注的通知方法在目标方法前、后都被执行@Before:前置通知,此注解标注的通知方法在目标方法前被执行@After:后置通知,此注解标注的通知方法在目标方法后被执行,无论是否有异常都会执行@AfterReturning: 返回后通知,此注解标注的通知方法在目标方法后被执行,有异常不会执行@AfterThrowing: 异常后通知,此注解标注的通知方法发生异常后执行
1 | |
2.6 @Transactional-声明式事务管理注解
可以让某段代码(通常是 Service 方法)在一个数据库事务中执行,要么全部成功,要么全部失败(回滚)
| 功能 | 描述 |
|---|---|
| 原子性(Atomicity) | 全部成功,全失败 |
| 一致性(Consistency) | 数据保持一致性 |
| 隔离性(Isolation) | 并发下保证数据隔离 |
| 持久性(Durability) | 提交后数据永久保存 |
| 异常自动回滚 | RuntimeException / Error 默认回滚 |
1 | |
如果减少库存时抛异常,insertOrder 也会自动回滚
常用属性
- rollbackFor(很重要)
默认只对 运行时异常 回滚
如果你希望对受检异常也回滚:
1 | |
- propagation(事务传播行为)
控制方法之间事务的嵌套与传播方式
| 值 | 描述 |
|---|---|
| REQUIRED(默认) | 有事务就加入,没有就创建一个 |
| REQUIRES_NEW | 总是创建新事务 |
| SUPPORTS | 有事务就加入,没有就无事务执行 |
| NOT_SUPPORTED | 强制不用事务 |
| MANDATORY | 必须在现有事务下执行,否则报错 |
| NEVER | 不能在事务内执行,有事务就报错 |
| NESTED | 创建嵌套事务(子事务) |
- isolation(隔离级别)
控制并发时的读取行为:
| 级别 | 描述 |
|---|---|
| READ_UNCOMMITTED | 最低,允许脏读 |
| READ_COMMITTED | Oracle/MySQL 默认,不允许脏读 |
| REPEATABLE_READ | MySQL 默认,保证重复读 |
| SERIALIZABLE | 最强,几乎不并发了 |
2.7 @Cacheable
将方法的返回结果缓存起来,当下次再以相同参数调用该方法时,就直接从缓存中取值,而不再执行方法逻辑。
常见属性:
| 属性 | 作用 |
|---|---|
value 或 cacheNames |
指定缓存名称(必填) |
key |
指定缓存键(默认是方法参数) |
condition |
满足条件才缓存 |
unless |
满足条件不缓存 |
keyGenerator |
自定义 Key 生成器 |
sync |
是否启用同步缓存(防止并发) |
假设我们有一个用户查询接口,从数据库查用户信息:
1 | |
调用两次:
1 | |
输出结果:第一次查询数据库,第二次直接查询缓存
1 | |
2.8 SpringCloud常用的注解
- @FeignClient: 让你像调用本地方法一样调用远程服务的 HTTP 接口
- @LoadBalanced: 启用负载均衡能力
2.8.1 @FeignClient/@EnableFeignClients
@FeignClient 是 Spring Cloud OpenFeign 提供的注解
在 Spring Cloud 微服务体系中,常见有多个独立模块
- 当你想在微服务1调用微服务2的接口时,就需要用
@FeignClient
1️⃣ 步骤一:开启Feign功能(@EnableFeignClients)
1 | |
2️⃣ 步骤二:创建Feign接口
1 | |
这个接口不需要写实现类,Spring Cloud 会在运行时自动创建一个代理类,帮你发起 HTTP 请求
3️⃣ 步骤三:在其他服务中注入使用
2.8.2 @LoadBalanced
@LoadBalanced 是 Spring Cloud LoadBalancer 提供的注解
让你的 RestTemplate 或 WebClient 具备通过服务名进行调用的能力,并自动实现负载均衡
在微服务架构中,我们通常有多个服务实例,例如:
| 服务名 | 实例 | 地址 |
|---|---|---|
| aimin-auth | 2个 | 192.168.1.10:8081, 192.168.1.11:8081 |
| aimin-admin | 1个 | 192.168.1.20:8084 |
如果你在 aimin-admin 里想调用 aimin-auth 的接口:使用服务名 + @LoadBalanced
1 | |
此时你就可以直接使用服务名:
1 | |
Spring Cloud 会:
- 从注册中心(如 Nacos、Eureka)获取所有 aimin-auth 实例;
- 自动选择一个实例;
- 发送请求,实现客户端负载均衡。
2.9 @Validated/@Valid
@Validated启用规范的校验机制,用于校验方法参数、类、或请求体的合法性
| 使用位置 | 示例 | 作用 |
|---|---|---|
| Controller 参数上 | @RequestBody @Validated UserDTO user |
校验前端传入的 JSON 对象 |
| 类上 | @Validated |
启用分组校验 |
| 方法上 | @Validated |
校验方法参数(结合 @Min、@NotBlank 等) |
@Validated最常见的使用方式
1 | |
与@Valid的区别:
| 对比项 | @Valid(JDK 标准) |
@Validated(Spring 扩展) |
|---|---|---|
| 是否支持分组校验 | ❌ 不支持 | ✅ 支持(常用于多场景校验) |
| 是否能用在方法级参数校验 | 部分支持 | ✅ 完全支持(推荐) |
| 场景 | 简单单一校验 | 复杂业务、分组场景 |
实际开发中建议:
- Controller层用
@Validated - POJO上用 Hibernate 校验注解(
@NotNull、@Email、@Size等)
3. Lombok第三方框架的常用注解
- @Getter: 为所有字段生成 getter 方法
- @Setter: 为所有字段生成 setter 方法
- @ToString: 自动生成 toString() 方法
- @Data: 组合注解:@Getter + @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor,最常用于实体类、DTO
- @EqualsAndHashCode: 生成 equals() 和 hashCode()
- @NoArgsConstructor: 无参构造方法
- @AllArgsConstructor: 全参数构造方法
- @Slf4j: 生成一个 Logger 日志对象,用于所有需要打印日志的类
- @RequiredArgsConstructor:为类中所有
final字段和所有带@NonNull注解的字段自动生成一个包含这些字段的构造方法。
3.1 @Getter/@Setter
为当前类中的 所有属性自动生成 getter 和 setter 方法,避免手写。
1 | |
等价于手动写:
1 | |
3.2 @ToString
自动生成 toString() 方法,输出对象内容,方便调试。
1 | |
打印:
1 | |
3.3 @Data
一个组合注解,相当于:
@Getter@Setter@ToString@EqualsAndHashCode@RequiredArgsConstructor
最常用于实体类、DTO、VO。
1 | |
等同于写大量 getter/setter/toString/equals 构造方法。
3.4 @EqualsAndHashCode
自动生成 equals() 和 hashCode() 方法,用于对象比较或放入 Set/Map 作为 key。
1 | |
效果类似:
1 | |
3.5 @NoArgsConstructor / @AllArgsConstructor
@NoArgsConstructor:生成无参构造方法@AllArgsConstructor:生成包含所有字段的构造方法
常用于框架要求(如反序列化)或快速创建对象。
1 | |
等价于:
1 | |
3.6 @Slf4j
为类自动生成一个日志对象, 原本:
1 | |
用于打印日志,不用手动写 Logger。
1 | |
3.7 @RequiredArgsConstructor
为类中所有 final 字段和所有带 @NonNull 注解的字段自动生成一个包含这些字段的构造方法。
假设我们有一个类:
1 | |
Lombok 会自动生成:
1 | |
这个构造方法只包含了含有final的userRepository和emailService这两个字段,并没有包含常规的字段threshold
为什么使用@RequiredArgsConstructor?
RequiredArgsConstructor 的含义是:
- 为所有“必需初始化”的字段生成构造器。
而“必需初始化”的字段包括:
✔ final
- 一定要在构造期间赋值
- 否则对象创建不完整
✔ @NonNull
- 推断为“业务上必须提供的参数”
- Lombok 会强制要求构造器传值,否则抛出 NPE
例如:
1 | |
生成:
1 | |
4. Swagger/OpenAPI3 常用注解
以下这些注解帮助生成我们的接口文档Swagger,从而使我们通过接口文档调试我们的接口。
| 分类 | 注解 | 用途 |
|---|---|---|
| 接口级别 | @Operation |
描述一个 API 方法(标题、描述、参数等) |
@Tag |
给 Controller 分组(类似旧版 @Api) |
|
| 参数、响应 | @Parameter |
描述 Query / Path 参数 |
@Parameters |
多个 @Parameter | |
@Schema |
描述 model 类或字段 |
4.1 @Tag
用于标记 Controller 分组
1 | |
4.2 @Operation
描述某个接口(方法)的用途
1 | |
4.3 @Parameter
描述路径参数(Path)或查询参数(Query)
1 | |
4.4 @Schema
用于描述类和属性,是模型文档的核心
1 | |
5. MyBatis / MyBatis-Plus 常用注解
| 注解 | 作用 |
|---|---|
| @Mapper | 标记 Mapper 接口,为其创建代理对象 |
| @Select/Insert/Update/Delete | 直接写 SQL 的注解 |
| @TableName | 实体类对应表名 |
| @TableId | 主键字段及策略 |
| @TableField | 字段映射控制(列名、忽略字段) |
| @Version | 乐观锁字段 |
| @TableLogic | 逻辑删除字段 |
5.1 @Mapper
标记当前接口是一个 MyBatis 的 Mapper,让 Spring 能扫描并创建它的代理对象。
编写数据库访问层(DAO)接口时使用。
1 | |
Spring 在启动时会帮你生成一个代理对象(实现类),然后能够自动注入
5.2 @MapperScan
指定 Mapper 接口所在包路径,自动扫描包下所有的Mapper接口,批量注册成Bean
1 | |
- 把 com.oimc.aimin.admin.mapper 包下的所有接口都当成 Mapper
- 自动给它们创建代理对象
| 比较项 | @Mapper |
@MapperScan |
|---|---|---|
| 作用对象 | 单个 Mapper 接口 | 整个包(批量生效) |
| 写法 | 写在每个 Mapper 接口上 | 在配置类/启动类写一次 |
| 是否方便 | ❌ Mapper 多时非常麻烦 | ✔ 一行配置搞定全部 |
| 推荐程度 | 不推荐大量使用 | ✔ 企业项目普遍使用 |
| Spring 识别方式 | 接口级别注解 | 包扫描式注解 |
5.3 @Select / @Insert / @Update / @Delete
这些是 MyBatis 的注解 SQL 方法,允许你直接在 Mapper 方法上编写 SQL,适合简单 SQL
- 适用于非常简单的 SQL 或测试环境。
- 复杂 SQL 应该写在 XML 中。
1 | |
5.4 @TableName
在 MyBatis-Plus 中,用来指定该实体类对应数据库的表名
- 实体类名和表名不一致时必须写
1 | |
5.5 @TableId
标识实体类中的主键字段,并可以指定主键生成策略。
| 策略 | 含义 |
|---|---|
IdType.AUTO |
数据库自增 |
IdType.ASSIGN_ID |
MP 自动生成(雪花算法) |
IdType.INPUT |
需要手动设置主键 |
1 | |
5.6 @TableField
指定实体类字段与数据库表字段的映射关系,或设置字段不参与查询、更新
- 字段名与数据库列名不同
1 | |