万字知识篇(2):SpringBoot的常用注解(上)
SpringBoot的常用注解非常的多,一篇文章根本讲不完,将分为上下两章,通过本章你将会系统的学习到:
- 1. 注解在
SpringBoot
中的作用 - 2.
SpringBoot
常用注解速查表 - 3. 核心启动类注解
- 4. @Configuration
- 5. @Bean
- 6. @PropertySource
- 7. @Value
- 8. @ConfigurationProperties
- 9. @Import
- 10. @Autowired
- 11. @Qualifier
- 12. @Primary
- 13. @Lazy
文章目录
- 一、SpringBoot的注解
- 1.1 注解在SpringBoot中的作用
- 1.2 SpringBoot 常用注解速查表
- 二、核心启动类注解
- 三、配置类注解
- 3.1 @Configuration
- 3.2 @Bean
- 3.3 @PropertySource
- 3.4 @Value(依赖注入注解)
- 3.5 @ConfigurationProperties
- 3.6 @Import
- 四、依赖注入注解
- 4.1 @Autowired
- 4.2 @Qualifier
- 4.3 @Primary
- 4.4 @Lazy
一、SpringBoot的注解
1.1 注解在SpringBoot中的作用
说到SpringBoo
t的注解,那我们先来说一下注解在SpringBoot
中起到了什么作用。SpringBoot
采用 “约定优于配置” 的理念,使用注解替代传统的 XML
配置,使代码更简洁、易读。例如我们可以使用@Configuration
它的作用是声明一个类为配置类,他会替代 XML配置文件
。
1.2 SpringBoot 常用注解速查表
我们先来快速的了解一下常用的注解,然后再详细的讲解这些。
分类 | 注解 | 功能说明 |
---|---|---|
核心启动类 | @SpringBootApplication | 核心启动注解,整合了 @Configuration 、@EnableAutoConfiguration 和 @ComponentScan ,启用自动配置和组件扫描 |
核心启动类 | @EnableAutoConfiguration | 启用 Spring Boot 的自动配置机制,根据依赖自动配置 Spring 应用 |
核心启动类 | @ComponentScan | 自动扫描指定包及其子包下的 Spring 组件(@Component 、@Service 等) |
核心启动类 | @SpringBootConfiguration | 标记当前类为 Spring Boot 的配置类,等价于传统的 @Configuration 注解 |
配置类 | @Configuration | 标记类为 Spring 配置类,替代 XML 配置文件 |
配置类 | @Bean | 声明方法返回的对象由 Spring IoC 容器管理,支持单例/原型作用域 |
配置类 | @PropertySource | 加载指定的 properties/yml 配置文件,支持多文件加载和编码设置 |
配置类 | @ConfigurationProperties | 将配置文件中的属性批量绑定到 Java 对象,支持嵌套属性和松散绑定 |
配置类 | @Import | 导入其他配置类或普通类到当前 Spring 上下文 |
依赖注入 | @Autowired | 自动按类型注入依赖,支持构造器/Setter/字段注入,优先按类型匹配 |
依赖注入 | @Qualifier | 配合 @Autowired 使用,按指定名称注入 Bean,解决类型冲突 |
依赖注入 | @Primary | 标记优先注入的 Bean,当存在多个同类型 Bean 时生效 |
依赖注入 | @Value | 注入属性值,支持 SpEL 表达式和默认值(${key:default} ) |
依赖注入 | @Lazy | 延迟初始化 Bean,首次请求时才会创建 |
Web 开发 | @RestController | 组合注解,包含 @Controller 和 @ResponseBody ,直接返回 JSON/XML 响应 |
Web 开发 | @RequestMapping | 定义请求映射路径,可通过 method 指定 HTTP 方法(GET/POST 等) |
Web 开发 | @GetMapping | 专用于处理 GET 请求的简写形式,等同于 @RequestMapping(method=GET) |
Web 开发 | @PostMapping | 专用于处理 POST 请求的简写形式 |
Web 开发 | @PathVariable | 从 URI 模板中提取变量值,支持 required 和默认值设置 |
Web 开发 | @RequestParam | 获取查询参数或表单数据,支持参数名映射、必填校验和默认值 |
Web 开发 | @RequestBody | 将请求体内容(JSON/XML)反序列化为 Java 对象,支持校验 |
Web 开发 | @ResponseBody | 将方法返回值序列化为响应体(JSON/XML) |
Web 开发 | @ResponseStatus | 自定义 HTTP 响应状态码,可用于类或方法上 |
Web 开发 | @ExceptionHandler | 声明异常处理方法,处理特定异常并返回自定义响应 |
Web 开发 | @ControllerAdvice | 全局控制器增强,结合 @ExceptionHandler 实现统一异常处理 |
Web 开发 | @CrossOrigin | 启用跨域请求支持,可配置 origins、methods 等参数 |
Web 开发 | @CookieValue | 获取 Cookie 中的值,支持 required 和默认值 |
Web 开发 | @RequestHeader | 获取请求头中的值,支持 header 名映射和必填校验 |
Web 开发 | @SessionAttribute | 访问 session 中的属性 |
数据校验 | @Valid | 触发 JSR-303 校验,可级联校验嵌套对象 |
数据校验 | @Validated | Spring 的校验注解,支持分组校验 |
数据校验 | @NotNull | 校验字段不为 null |
数据校验 | @NotBlank | 校验字符串不为空且至少包含一个非空白字符 |
数据校验 | @Size | 校验集合/数组/字符串的大小在指定范围内 |
数据校验 | @Pattern | 校验字符串匹配正则表达式 |
数据校验 | @Email | 校验字符串为合法的邮箱格式 |
数据访问-JPA | @Entity | 标记类为 JPA 实体,对应数据库表 |
数据访问-JPA | @Table | 指定实体对应的数据库表名,默认使用类名 |
数据访问-JPA | @Id | 声明主键字段 |
数据访问-JPA | @GeneratedValue | 配置主键生成策略(IDENTITY/SEQUENCE/TABLE/AUTO) |
数据访问-JPA | @Column | 配置字段与数据库列的映射关系(name/length/unique 等) |
数据访问-JPA | @Transient | 标记字段不持久化到数据库 |
数据访问-JPA | @OneToMany | 定义一对多关联关系,可配置级联操作和加载策略 |
数据访问-JPA | @ManyToOne | 定义多对一关联关系 |
数据访问-JPA | @JoinColumn | 配置关联关系的数据库外键列 |
数据访问-MyBatis | @Mapper | 标记接口为 MyBatis Mapper,由 MyBatis 动态实现 |
数据访问-MyBatis | @Select | 声明 SQL 查询语句 |
数据访问-MyBatis | @Insert | 声明 SQL 插入语句 |
数据访问-MyBatis | @Update | 声明 SQL 更新语句 |
数据访问-MyBatis | @Delete | 声明 SQL 删除语句 |
数据访问-MyBatis | @Param | 指定 MyBatis 方法参数的名称 |
事务管理 | @Transactional | 声明事务,可配置隔离级别、传播行为、超时和只读属性 |
事务管理 | @EnableTransactionManagement | 启用声明式事务管理 |
定时任务 | @EnableScheduling | 启用定时任务支持 |
定时任务 | @Scheduled | 声明定时任务,支持 cron/fixedDelay/fixedRate 表达式 |
Spring Security | @EnableWebSecurity | 启用 Spring Security 配置 |
Spring Security | @PreAuthorize | 方法级权限控制,支持 SpEL 表达式(如 hasRole('ADMIN') ) |
Spring Security | @PostAuthorize | 方法执行后进行权限校验 |
Spring Security | @Secured | 基于角色列表的权限控制(需启用 @EnableGlobalMethodSecurity ) |
Spring Security | @EnableGlobalMethodSecurity | 启用方法级安全控制 |
测试 | @SpringBootTest | 标记 Spring Boot 集成测试类,加载完整应用上下文 |
测试 | @DataJpaTest | 仅加载 JPA 相关配置的切片测试 |
测试 | @WebMvcTest | 仅加载 Web MVC 相关配置的切片测试 |
测试 | @MockBean | 向 Spring 上下文注入 Mock 对象,替代真实 Bean |
测试 | @SpyBean | 向 Spring 上下文注入 Spy 对象,部分 Mock 真实 Bean |
测试 | @TestConfiguration | 定义测试专用的配置类,不会影响主配置 |
二、核心启动类注解
在 SpringBoot
中,核心启动类是整个应用的入口,而 @SpringBootApplication
是启动类的核心注解。它的作用远不止标记一个类为启动类,而是通过组合多个关键注解实现自动化配置和组件扫描。
- 作用目标:类(必须标注在主类上)
- 核心功能:这是 SpringBoot 应用的核心入口注解,本质上是三个关键注解的组合。
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication { ... }
(1) @SpringBootConfiguration
功能:
- 标记当前类为 Spring Boot 的配置类,等价于传统的 @Configuration 注解。
- 表明该类中可能包含通过 @Bean 注解定义的 Spring 容器管理的对象。
(2) @EnableAutoConfiguration
功能:
- 启用
SpringBoot
的自动配置机制,根据项目的依赖(如spring-boot-starter-web、spring-boot-starter-data-jpa
)自动配置Spring
应用。 - 自动加载文件中定义的配置类(如
DataSourceAutoConfiguration
、WebMvcAutoConfiguration
)。
工作原理:
- 扫描类路径下的
JAR
包,检测是否有预定义的配置类(如发现HikariDataSource
则自动配置数据源)。 - 根据条件注解(如
@ConditionalOnClass
、@ConditionalOnMissingBean
)动态决定是否启用配置。
(3) @ComponentScan
功能:
- 自动扫描当前包及其子包下的组件,包括
@Component
、@Service
、@Repository
、@Controller
等注解标记的类。 - 将这些组件注册为
SpringBean
,无需手动在XML
或JavaConfig
中定义。
默认扫描路径:
- 主启动类所在的包作为根包。
- 若主类在
com.example.demo
包下,则自动扫描com.example.demo
及其子包。
三、配置类注解
3.1 @Configuration
作用:标记一个类为配置类,告诉Spring容器
这个类是用来定义Bean
的。
想象你要开一家奶茶店,@Configuration 就像是你的 “开店指导手册”,用来告诉 Spring(你的开店助手)两件事:
1.“这个类很重要!”
- 就像在手册封面写上《XX奶茶店操作指南》,告诉助手:“这是我们的核心配置”。
2.“这里有制作奶茶的配方!”
- 手册里的每个方法(用 @Bean 标记)都是一个具体配方,比如:
- “珍珠奶茶配方”
- “芝士奶盖配方”
当 Spring 看到 @Configuration 时:
- 会把这个类 当作特殊说明书 加载
- 执行里面所有带
@Bean
的方法,把返回的对象 存入"原料仓库"(Spring 容器
) - 其他类需要时,直接问仓库要(通过
@Autowired
)
和普通类的区别
普通类 | @Configuration 类 |
---|---|
Spring 当它是路人甲 | Spring 当它是 VIP 说明书 |
里面的方法随便写 | 带 @Bean 的方法会被特殊处理 |
不会被自动调用 | Spring 会主动执行所有 @Bean 方法 |
3.2 @Bean
作用:用于声明一个Bean
。被@Bean
注解标记的方法会被Spring容器
调用,并将返回的对象纳入管理。
@Bean 是 Spring 中的一个重要注解,它的作用就是 告诉 Spring:这个方法会返回一个对象,你要把这个对象管理起来!
简单来说,@Bean 就是 手工造零件,然后交给 Spring 的“零件仓库”(IoC 容器)去管理,其他类要用的时候,Spring 会自动提供。
@Configuration // 这是一本开店手册
public class TeaShopConfig {
@Bean // 这是"珍珠奶茶"的配方
public MilkTea pearlMilkTea() {
MilkTea tea = new MilkTea();
tea.addIngredient("珍珠");
tea.addIngredient("红茶");
return tea;
}
@Bean // 这是"芝士奶盖"的配方
public CheeseFoam cheeseFoam() {
return new CheeseFoam();
}
}
虽然 @Bean
不一定必须用在 @Configuration
类中,但为了代码的可读性和维护性,建议将@Bean
方法集中放在 @Configuration
类中。
3.3 @PropertySource
作用:用于加载指定的属性文件到 Spring
的环境中,从而可以在应用中使用这些属性值。
功能:
- 加载指定的
.properties
或.yml
文件 - 将文件中的属性添加到
Spring
的Environment
中 - 支持通过
@Value
或Environment
对象获取属性值
路径可以是类路径下的资源文件(使用 classpath: 前缀)。在 Spring 框架中,使用 classpath: 前缀时,Spring 会自动在应用程序的 类路径(Classpath) 中查找资源文件类路径通常包括以下几个部分:
- 项目的 src/main/resources 目录:在 Maven 或 Gradle 项目中,src/main/resources 是存放资源文件的标准目录。
- 这些文件在构建过程中会被复制到目标输出目录(如 target/classes 或 build/classes)。
- 如果资源文件位于类路径下的某个子目录中,可以通过路径来指定。例如:
@PropertySource("classpath:config/my.properties")
@Configuration
@PropertySource("classpath:application.yml")
public class TestConfigure {
}
springBoot中属性加载优先级:
- application.properties (最高优先级)
- @PropertySource 指定的文件
- 系统环境变量
- 命令行参数
同时还能加载多个配置文件
@Configuration
@PropertySources({
@PropertySource("classpath:default.properties"),
@PropertySource("classpath:env-specific.properties")
})
public class AppConfig { ... }
避免加载 application.properties
不推荐使用@PropertySource
加载以 application
为前缀的配置文件(如 application-dev.properties
),因为这些文件通常会被 SpringBoot
自动加载,可能导致配置值被覆盖。
不支持直接加载 YAML 格式的配置文件
@PropertySource
注解本身不支持直接加载 YAML
格式的配置文件。@PropertySource
主要用于加载 .properties
文件,而不是 .yml
文件。如果你尝试使用 @PropertySource
加载 .yml
文件,Spring
会抛出错误,因为 @PropertySource
默认只支持 .properties
格式的文件。
3.4 @Value(依赖注入注解)
@Value
是 Spring
中一个非常常用的注解,主要用于将配置文件中的值注入到 Spring
管理的 Bean
中。它可以从配置文件(如 application.properties
或 application.yml
)中读取属性值,也可配合上述讲过的注解@PropertySource
指定的文件的文件读入属性,并将其注入到字段、构造函数或方法参数中。
功能:
- 从配置文件读取值(比如 application.properties)
- 注入系统环境变量
- 直接赋固定值
- 支持 SpEL 表达式(可以算数学题、调用方法等)
看一个小例子:
在配置类中使用value注入属性
没有问题,成功注入,Spring 会主动执行所有 @Bean 方法,而且application.yml是spring自动导入的一个注解文件,不用我们在显示的引入这个文件。
那如果我们需要的值在Value.properties下面呢?
服务器报错了
我们需要用@PropertySource注入value.properties
没问题
3.5 @ConfigurationProperties
作用:
将配置文件(如 application.properties
或 application.yml
)中的属性值绑定到一个 Java
对象的字段上。它支持松散绑定,即配置文件中的属性名可以与 Java
字段名不完全一致,但可以通过一定的规则进行匹配。
假设你的 application.yml 里有这样一段配置:
如果用 @Value,你要写很多重复代码:
而用 @ConfigurationProperties,你可以:
✅ 自动绑定整个配置段到一个 Java 对象
✅ 支持嵌套属性
✅ 自动类型转换(String → int/boolean 等)
✅ 提供 IDE 自动提示(配合 spring-boot-configuration-processor)
之后就可以在别的地方使用了
成功注入,没有问题
3.6 @Import
作用:
将一个或多个配置类引入到当前配置类中,从而实现模块化的配置管理。
主要功能:
- 引入其他配置类:可以将其他
@Configuration
类导入到当前配置类中 - 引入普通类:可以将普通类作为
bean
定义导入到Spring
容器中 - 引入
ImportSelector
实现:可以动态选择要导入的配置 - 引入
ImportBeanDefinitionRegistrar
实现:可以编程式地注册bean
定义
@Configuration
class DatabaseConfig {
@Bean
public DataSource dataSource() {
// 数据源配置
}
}
@Configuration
@Import(DatabaseConfig.class)
class AppConfig {
// 现在可以使用DatabaseConfig中定义的bean
}
public class Service {
// 业务逻辑
}
@Configuration
@Import(Service.class)
class AppConfig {
// Service类将被注册为Spring bean
}
四、依赖注入注解
4.1 @Autowired
@Autowired
是 Spring
框架中最核心的注解之一,用于实现依赖注入DI
。
基本作用
@Autowired
的主要功能是自动装配 Spring
容器中的 bean
:
- 自动为类成员(字段、构造器、方法)注入依赖对象
- 消除显式的
getter/setter
和手动装配代码 - 是
Spring
依赖注入的核心实现方式
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
}
上述这种方式是Spring
不推荐的方式,Spring
推荐的方式是通过构造函数注入
@RestController
@RequestMapping("/dept")
@Tag(name = "组织结构管理")
@Slf4j
public class DepartmentController {
private final DepartmentService departmentService;
private final UserService userService;
@Autowired // 构造函数注入
public DepartmentController(DepartmentService departmentService, UserService userService) {
this.departmentService = departmentService;
this.userService = userService;
}
}
在Spring 4.3+
后,如果一个类里面只有一个构造函数,可省略 @Autowired
@RestController
@RequestMapping("/dept")
@Tag(name = "组织结构管理")
@Slf4j
public class DepartmentController {
private final DepartmentService departmentService;
private final UserService userService;
public DepartmentController(DepartmentService departmentService, UserService userService) {
this.departmentService = departmentService;
this.userService = userService;
}
}
同时也是可选依赖
@Autowired(required = false)
private OptionalDependency dependency; // 找不到bean时不报错
4.2 @Qualifier
@Qualifier
是 Spring
框架中用于解决依赖注入歧义性的重要注解,通常与 @Autowired
配合使用。下面我将全面讲解这个注解的用法和工作原理。
基本作用
@Qualifier 的主要功能是:
- 当存在多个相同类型的 Bean 时,明确指定要注入哪一个
- 为自动装配过程提供额外的筛选条件
- 实现更精确的依赖注入控制
@Configuration
public class AppConfig {
@Bean
public DataSource masterDataSource() {
return new MasterDataSource();
}
@Bean
public DataSource slaveDataSource() {
return new SlaveDataSource();
}
}
@Service
public class UserService {
@Autowired
@Qualifier("masterDataSource") // 明确指定bean名称
private DataSource dataSource;
}
4.3 @Primary
@Primary
是 Spring
框架中用于标记首选的 Bean
的注解,当存在多个相同类型的 Bean
时,被标记为 @Primary
的 Bean
会被优先选择。
基本作用:
@Primary
的主要功能是:
- 当存在多个相同类型的
Bean
时,指定默认注入的候选者 - 解决自动装配时的歧义性问题
- 作为隐式的、默认的选择机制
@Configuration
public class DataSourceConfig {
@Bean
@Primary // 被标记为首选Bean
public DataSource primaryDataSource() {
return new PrimaryDataSource();
}
@Bean
public DataSource secondaryDataSource() {
return new SecondaryDataSource();
}
}
@Service
public class UserService {
@Autowired
private DataSource dataSource; // 会自动注入primaryDataSource
}
当然,它还可以在类(组件)上面使用,达到优先级的目的
@Primary
@Service
public class PrimaryPaymentService implements PaymentService {
// 实现代码
}
@Service
public class SecondaryPaymentService implements PaymentService {
// 实现代码
}
与 @Qualifier 的优先级
- 当同时存在
@Primary
和@Qualifier
时,@Qualifier
的优先级更高 @Primary
是一种"默认"机制,而@Qualifier
是"显式指定"机制
4.4 @Lazy
@Lazy
是 Spring
框架中用于延迟初始化的重要注解,它可以控制 Bean
的加载时机,优化应用启动性能并解决某些特殊依赖问题。
基本作用
@Lazy
的主要功能是:
- 延迟
Bean
的初始化(推迟到第一次被使用时才创建) - 解决循环依赖问题
- 优化应用启动性能(减少启动时加载的
Bean
数量)
@Configuration
public class AppConfig {
@Bean
@Lazy // 延迟初始化
public ExpensiveService expensiveService() {
return new ExpensiveService(); // 耗时的初始化操作
}
}