JAVA面试|spring boot常用注解(springboot有什么注解)
liuian 2025-07-27 21:58 20 浏览
Spring Boot的核心就是通过注解简化配置,让开发者更专注于业务逻辑。下面是一些最常用、最核心的注解,用通俗的方式解释它们的作用和典型使用场景:
一、核心启动与配置
1. @SpringBootApplication
作用:超级核心注解!标记在Spring Boot应用的主类(包含main方法的类)上。它是三个关键注解的组合:
@SpringBootConfiguration:表明这个类是一个Spring Boot的配置类(基于@Configuration)。
@EnableAutoConfiguration:开启Spring Boot的魔法-自动配置!根据你引入的jar包依赖(如spring-boot-starter-web,
spring-boot-starter-data-jpa),Spring Boot会自动配置应用所需的基础组件(如Web服务器、数据库连接池等)。
@ComponentScan:启动组件扫描。告诉Spring从当前类所在的包及其子包下扫描带有@Component,@Service,@Repository, @Controller, @RestController等注解的类,并自动将它们注册为 Spring容器管理的Bean。
场景:每个Spring Boot应用都必须有一个类标注它,这是应用的入口点。例如:
@SpringBootApplication
public class MyAwesomeApplication {
public static void main(String[] args) {
SpringApplication.run(
MyAwesomeApplication.class, args); // 启动应用
}
}
二、定义Bean(组件)
这些注解告诉Spring:“请管理这个类的实例(Bean),并在需要的地方自动注入它们。”
1. @Component
作用:通用组件标记。标注一个类,表示它是一个Spring管理的组件(Bean)。Spring在扫描时会创建它的实例放入容器。
场景:适用于那些不属于Controller、Service、Repository层,但又需要被Spring管理的工具类、辅助类、自定义组件等。例如:一个通用的邮件发送工具类EmailSender。
2. @Service
作用:标记业务逻辑层(Service层)的组件。本质上它也是 @Component的一种特化,语义上更清晰,表明这个类包含业务逻辑。
场景:定义处理核心业务规则的Service类。例如:UserService(处理用户注册、登录、查询等业务)、OrderService(处理订单创建、支付、查询等业务)。
3. @Repository
作用:标记数据访问层(DAO层)的组件。本质上也是@Component 的特化。它有一个额外的好处:它会自动将数据访问层抛出的特定异常(如JDBC的SQLException)转换为Spring统一的数据访问异常(DataAccessException),使异常处理更一致。
场景:定义访问数据库的DAO接口实现类。通常与JPA、MyBatis 等ORM框架结合使用。例如:UserRepository(定义用户数据的增删改查操作)、ProductRepository。
4. @Controller
作用:标记Web层的控制器组件(传统MVC)。处理 HTTP请求,协调模型(Model)和视图(View)。通常需要配合@RequestMapping 等注解使用。返回的结果通常是一个视图名(如JSP、Thymeleaf模板名),由视图解析器解析渲染。
场景:在需要返回HTML页面(服务器端渲染)的Web应用中定义控制器。例如:处理页面跳转、表单提交的控制器。
5. @RestController
作用:@Controller +@ResponseBody的组合体!专门用于构建 RESTful Web服务。标注的类下的所有方法默认会将返回值直接序列化成JSON/XML写入HTTP响应体,而不是解析为视图名。
场景:现代前后端分离应用的主流控制器注解。定义提供API接口的控制器。例如:提供用户管理、订单管理等API的 UserController, OrderController。
6. @Configuration
作用:标记一个类为配置类。这个类的作用类似于传统的XML配置文件(如applicationContext.xml)。在这个类内部,你可以使用@Bean注解来显式地定义和配置Spring Bean。
场景:
需要手动配置一些第三方库的Bean(Spring Boot自动配置不满足需求时)。
定义一些复杂的Bean,需要编写初始化代码。
替代XML配置文件。例如:
@Configuration
public class MyAppConfig {
@Bean // 告诉Spring这个方法的返回值是一个需要管理的Bean
public MySpecialService mySpecialService() {
return new MySpecialServiceImpl(someDependency()); // 可以在这里进行复杂的构造或配置
}
}
7. @Bean
作用:用在@Configuration类的方法上。告诉Spring:这个方法返回的对象应该被注册为Spring应用上下文中的一个Bean。方法名通常作为Bean的名称。
场景:当你想显式地、编程式地创建和配置一个Bean实例时使用。常用于配置数据源(DataSource)、事务管理器 (
PlatformTransactionManager)、第三方库的组件等。例如在配置类中配置一个RestTemplate Bean:
@Configuration
public class RestConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
三、依赖注入
这些注解告诉Spring:“请在这个地方自动给我一个合适类型的Bean实例。”
1. @Autowired
作用:自动装配(注入)依赖。Spring会自动在容器中查找匹配类型(或名称)的Bean,并将其注入到标注了@Autowired的位置(构造器、字段、Setter方法、普通方法)。
场景:非常非常常用! 当你的Bean(如Service)需要依赖另一个 Bean(如Repository)时使用。例如:
@Service
public class UserService {
private final UserRepository userRepository; // 依赖
@Autowired // 构造器注入 (推荐方式)
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
// 或者字段注入 (不推荐,容易导致循环依赖等问题)
// @Autowired
// private UserRepository userRepository;
// 或者Setter方法注入
// @Autowired
// public void setUserRepository(UserRepository userRepository) {
// this.userRepository = userRepository;
// }
}
注意:Spring 4.3以后,如果类只有一个构造器,@Autowired可以省略。
2. @Qualifier
作用:配合@Autowired使用,解决自动装配时的歧义性。当容器中存在多个相同类型的Bean时,用@Qualifier指定要注入的Bean 的具体名称。
场景:定义了多个同类型Bean时。例如有两个DataSource Bean,一个用于主库 (@Primary),一个用于从库。在需要注入从库的地方:
@Autowired
@Qualifier("secondaryDataSource") // 指定Bean的名称
private DataSource dataSource;
3. @Primary
作用:标记一个Bean为首选Bean。当存在多个相同类型的Bean 且没有明确指定@Qualifier时,Spring会优先注入带有@Primary注解的那个。
场景:定义了多个同类型Bean,但希望其中一个作为默认注入项时。例如,配置主数据源:
@Configuration
public class DataSourceConfig {
@Bean
@Primary // 标记为主数据源
public DataSource primaryDataSource() { ... }
@Bean
public DataSource secondaryDataSource() { ... }
}
4. @Value
作用:注入属性值。主要用于注入外部配置文件(如
application.properties/application.yml)中定义的属性值,也可以注入简单的字面量(字符串、数字等)或SpEL表达式。
场景:
读取配置文件中的配置项(数据库连接、服务端口、开关标志等)。
注入简单的常量。
例如:
@Service
public class MyService {
@Value("${app.page.size}") // 注入配置文件中的 app.page.size 属性
private int pageSize;
@Value("Hello World") // 直接注入字符串
private String greeting;
@Value("#{systemProperties['user.home']}") // 使用SpEL注入系统属性
private String userHome;
}
在application.properties中:app.page.size=20
四、Web开发(Controller层)
1. @RequestMapping
作用:映射HTTP请求到控制器方法。可以定义在类上(表示类中所有方法的公共路径前缀)或方法上(指定具体的URL路径、HTTP 方法等)。它是其他更具体注解(如@GetMapping, @PostMapping)的基础。
场景:定义API或页面的访问路径和处理逻辑。例如:
@RestController
@RequestMapping("/api/users") // 类级别的路径前缀
public class UserController {
@RequestMapping(method = RequestMethod.GET) // 老式写法,等同于 @GetMapping
public List<User> getAllUsers() { ... }
@RequestMapping(value = "/{id}", method = RequestMethod.GET) // 老式写法,等同于 @GetMapping("/{id}")
public User getUserById(@PathVariable Long id) { ... }
}
2. @GetMapping,@PostMapping,@PutMapping, @DeleteMapping, @PatchMapping
作用:@RequestMapping的快捷特化注解。分别对应HTTP的GET, POST,PUT, DELETE, PATCH方法。它们内部已经指定了method属性,使代码更简洁清晰。
场景:现代RESTful控制器方法的标准写法。明确指定方法处理的HTTP动作。例如:
@RestController
@RequestMapping("/api/products")
public class ProductController {
@GetMapping // 等同于 @RequestMapping(method=GET)
public List<Product> listProducts() { ... }
@PostMapping // 等同于 @RequestMapping(method=POST)
public Product createProduct(@RequestBody Product product) { ... }
@GetMapping("/{id}") // GET /api/products/123
public Product getProduct(@PathVariable Long id) { ... }
@PutMapping("/{id}") // PUT /api/products/123
public Product updateProduct(@PathVariable Long id, @RequestBody Product product) { ... }
@DeleteMapping("/{id}") // DELETE /api/products/123
public void deleteProduct(@PathVariable Long id) { ... }
}
3. @PathVariable
作用:将URL路径模板中的变量绑定到方法参数。
场景:处理RESTful风格的URL,其中包含动态ID或其他标识符。例如上面getProduct(@PathVariable Long id)中的id就是从 URL /products/{id}中提取的。
4. @RequestParam
作用:将HTTP请求参数(通常是查询字符串?key=value&key2=value2)绑定到方法参数。可以指定参数名称(如果与变量名不同)、是否必需、默认值。
场景:获取URL查询参数或表单提交(
application/x-www-form-urlencoded)的参数。例如:
@GetMapping("/search")
public List<Product> searchProducts(
@RequestParam String keyword, // 必需参数
@RequestParam(value = "page", defaultValue = "1") int page, // 可选参数,默认值1
@RequestParam(value = "size", required = false, defaultValue = "10") Integer size) { // 可选参数,默认值10
...
}
5. @RequestBody
作用:将HTTP请求体(通常是JSON或XML)绑定到方法参数对象。 Spring会根据请求的Content-Type头(如application/json)使用合适的消息转换器(如Jackson)进行反序列化。
场景:接收前端通过POST/PUT/PATCH请求发送的JSON/XML数据。 例如创建或更新资源时:
@PostMapping
public User createUser(@RequestBody User newUser) { // 将请求体JSON自动转换为User对象
return userService.save(newUser);
}
6. @ResponseBody
作用:将控制器方法的返回值直接写入HTTP响应体(而不是视图)。 通常由合适的消息转换器(如Jackson)序列化成JSON/XML。
场景:在@Controller注解的类中,某个方法需要返回数据(如 AJAX请求响应)而不是视图名时使用。注意:@RestController已经包含了@ResponseBody语义,所以其下的所有方法都默认有该行为,无需再单独标注。
7. @RestControllerAdvice/@ControllerAdvice
作用:定义全局的、应用于多个控制器的增强处理(如异常处理、数据绑定增强、模型属性增强)。@RestControllerAdvice是 @ControllerAdvice + @ResponseBody的组合,专用 RESTful服务,其内部方法返回值会直接写入响应体。
场景:统一异常处理(最重要、最常用)。集中处理整个应用中控制器抛出的异常,返回结构化的错误信息(JSON)。例如:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(
ResourceNotFoundException.class) // 处理特定异常
@ResponseStatus(HttpStatus.NOT_FOUND) // 设置响应状态码
public ErrorResponse handleResourceNotFound(ResourceNotFoundException ex) {
return new ErrorResponse("NOT_FOUND", ex.getMessage());
}
@ExceptionHandler(Exception.class) // 处理所有其他异常
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ErrorResponse handleGeneralException(Exception ex) {
return new ErrorResponse("INTERNAL_ERROR", "An unexpected error occurred");
}
}
五、配置与属性
1. @ConfigurationProperties
作用:将一组相关的配置属性(通常来自
application.properties/.yml)绑定到一个类型安全的Java Bean 上。 支持嵌套属性、验证等。
场景:管理复杂的外部配置。 避免在代码中到处使用@Value注入大量单个属性。例如配置数据库连接池、邮件服务器参数、第三方服务密钥等。需要结合@
EnableConfigurationProperties或在配置类上用@Bean注册。
定义配置类:
@ConfigurationProperties(prefix = "app.mail") // 绑定所有以 app.mail 开头的属性
@Data // Lombok 注解,生成getter/setter等
public class MailProperties {
private String host;
private int port;
private String username;
private String password;
private boolean sslEnabled = true; // 默认值
}
application.properties:
app.mail.host=smtp.example.com
app.mail.port=587
app.mail.username=admin@example.com
app.mail.password=secret
# app.mail.sslEnabled 没配置,使用默认值 true
启用并注入:
@Configuration
@
EnableConfigurationProperties(MailProperties.class) // 启用这个配置属性类
public class AppConfig {
// 也可以在其他地方 @Autowired MailProperties mailProperties;
}
2. @PropertySource
作用:指定自定义的属性文件(非默认的
application.properties/.yml)的位置,将其加载到Spring的 Environment中。
场景:将配置拆分到多个文件中,或者加载特定环境、模块的配置。例如:
@Configuration
@PropertySource("
classpath:config/database.properties") // 加载类路径下的 database.properties
@PropertySource("
file:/etc/myapp/secrets.properties") // 加载文件系统上的配置文件
public class DatabaseConfig {
// 可以使用 @Value 或 @ConfigurationProperties 读取这些文件中的属性
}
六、数据访问与事务
1. @Transactional
作用:声明式事务管理。标注在类或方法上,表示该方法/类中的所有public方法需要在事务上下文中执行。Spring会自动管理事务的开启、提交、回滚(通常在Service层方法上使用)。
场景:确保数据库操作的原子性。当一组数据库操作需要作为一个整体(要么全部成功,要么全部失败)时使用。例如转账操作:扣钱和加钱必须在同一个事务中。
七、条件化配置 (理解自动配置原理)
1. @ConditionalOn...系列(如@ConditionalOnClass, @ConditionalOnMissingBean, @ConditionalOnProperty)
作用:Spring Boot自动配置的基石!这些是条件注解。它们标注在配置类或@Bean方法上,只有当满足特定条件(如某个类在 classpath中存在、容器中不存在某个Bean、某个属性有特定值)时,才会生效对应的配置或创建对应的Bean。
场景:理解自动配置如何按需工作。例如,spring-boot-autoconfigure中的配置类大量使用它们:
@ConditionalOnClass(DataSource.class):只有当 DataSource 类在classpath 中(即你引入了JDBC或数据库驱动相关的starter)时,自动配置数据库相关的Bean才生效。
@ConditionalOnMissingBean(DataSource.class): 只有当容器中还没有DataSource类型的Bean时(即你自己没有手动配置),Spring Boot才会自动配置一个默认的数据源。
@ConditionalOnProperty(name = "app.feature.enabled", havingValue = "true"):只有当配置文件中有 app.feature.enabled=true 时,这个配置/Bean才生效。
八、总结
这些注解构成了Spring Boot开发的基础。掌握它们,你就能:
启动应用 (@SpringBootApplication)
定义组件 (@Component, @Service, @Repository, @Controller, @RestController, @Configuration, @Bean)
注入依赖 (@Autowired, @Qualifier, @Primary, @Value)
处理Web请求(@RequestMapping, @GetMapping等, @PathVariable, @RequestParam, @RequestBody, @ResponseBody, @RestControllerAdvice)
管理配置 (@ConfigurationProperties, @PropertySource)
控制事务 (@Transactional)
理解自动配置 (@ConditionalOn...)
记住,Spring Boot的哲学是“约定优于配置”。这些注解大部分都有合理的默认行为,让你用最少的配置完成大部分工作。随着深入,你会接触到更多特定场景的注解(如Spring Data JPA的@Entity, @Repository;Spring Security 的@EnableWebSecurity, @PreAuthorize 等),但上面列出的这些是构建Spring Boot应用的通用基石。
相关推荐
- 赶紧收藏!编程python基础知识,本文给你全部整理好了
-
想一起学习编程Python的同学,趁我粉丝少,可以留言、私信领编程资料~Python基础入门既然学习Python,那么至少得了解下这门编程语言,知道Python代码执行过程吧。Python的历...
- 创建绩效改进计划 (PIP) 的6个步骤
-
每个经理都必须与未能达到期望的员工抗衡,也许他们的表现下降了,他们被分配了新的任务并且无法处理它们,或者他们处理了自己的任务,但他们的行为对他人造成了破坏。许多公司转向警告系统,然后在这些情况下终止。...
- PI3K/AKT信号通路全解析:核心分子、上游激活与下游效应分子
-
PI3K/AKT/mTOR(PAM)信号通路是真核细胞中高度保守的信号转导网络,作用于促进细胞存活、生长和细胞周期进程。PAM轴上生长因子向转录因子的信号传导受到与其他多条信号通路的多重交叉相互作用的...
- 互联网公司要求签PIP,裁员连N+1都没了?
-
2021年刚画上句号,令无数互联网公司从业者闻风丧胆的绩效公布时间就到了,脉脉上已然炸了锅。阿里3.25、腾讯二星、百度四挡、美团绩效C,虽然名称五花八门,实际上都代表了差绩效。拿到差绩效,非但不能晋...
- Python自动化办公应用学习笔记3—— pip工具安装
-
3.1pip工具安装最常用且最高效的Python第三方库安装方式是采用pip工具安装。pip是Python包管理工具,提供了对Python包的查找、下载、安装、卸载的功能。pip是Python官方提...
- 单片机都是相通的_单片机是串行还是并行
-
作为一个七年的从业者,单片机对于我个人而言它是一种可编程的器件,现在长见到的电子产品中几乎都有单片机的身影,它们是以单片机为核心,根据不同的功能需求,搭建不同的电路,从8位的单片机到32位的单片机,甚...
- STM32F0单片机快速入门八 聊聊 Coolie DMA
-
1.苦力DMA世上本没有路,走的人多了,便成了路。世上本没有DMA,需要搬运的数据多了,便有了DMA。大多数同学应该没有在项目中用过这个东西,因为一般情况下也真不需要这个东西。在早期的单片机中...
- 放弃51单片机,直接学习STM32开发可能会面临的问题
-
学习51单片机并非仅仅是为了学习51本身,而是通过它学习一种方法,即如何仅仅依靠Datasheet和例程来学习一种新的芯片。51单片机相对较简单,是这个过程中最容易上手的选择,而AVR单片机则更为复杂...
- STM32串口通信基本原理_stm32串口原理图
-
通信接口背景知识设备之间通信的方式一般情况下,设备之间的通信方式可以分成并行通信和串行通信两种。并行与串行通信的区别如下表所示。串行通信的分类1、按照数据传送方向,分为:单工:数据传输只支持数据在一个...
- 单片机的程序有多大?_单片机的程序有多大内存
-
之前一直很奇怪一个问题,每次写好单片机程序之后,用烧录软件进行烧录时,能看到烧录文件也就是hex的文件大小:我用的单片机芯片是STM32F103C8T6,程序储存器(flash)只有64K。从...
- 解析STM32单片机定时器编码器模式及其应用场景
-
本文将对STM32单片机定时器编码器模式进行详细解析,包括介绍不同的编码器模式、各自的优缺点以及相同点和不同点的应用场景。通过阅读本文,读者将对STM32单片机定时器编码器模式有全面的了解。一、引言...
- 两STM32单片机串口通讯实验_两个32单片机间串口通信
-
一、实验思路连接两个STM32单片机的串口引脚,单片机A进行发送,单片机B进行接收。单片机B根据接收到单片机A的指令来点亮或熄灭板载LED灯,通过实验现象来验证是否通讯成功。二、实验器材两套STM32...
- 基于单片机的智能考勤机设计_基于51单片机的指纹考勤机
-
一、设计背景随着科技水平的不断发展,在这么一个信息化的时代,智能化信息处理已是提高效率、规范管理和客观审查的最有效途径。近几年来,国内很多公司都在加强对企业人员的管理,考勤作为企业的基础管理,是公司...
- STM32单片机详细教学(二):STM32系列单片机的介绍
-
大家好,今天给大家介绍STM32系列单片机,文章末尾附有本毕业设计的论文和源码的获取方式,可进群免费领取。前言STM32系列芯片是为要求高性能、低成本、低功耗的嵌入式应用设计的ARMCortexM...
- STM32单片机的 Hard-Fault 硬件错误问题追踪与分析
-
有过单片机开发经验的人应该都会遇到过硬件错误(Hard-Fault)的问题,对于这样的问题,有些问题比较容易查找,有些就查找起来很麻烦,甚至可能很久都找不到问题到底是出在哪里。特别是有时候出现一次,后...
- 一周热门
-
-
【验证码逆向专栏】vaptcha 手势验证码逆向分析
-
Python实现人事自动打卡,再也不会被批评
-
Psutil + Flask + Pyecharts + Bootstrap 开发动态可视化系统监控
-
一个解决支持HTML/CSS/JS网页转PDF(高质量)的终极解决方案
-
再见Swagger UI 国人开源了一款超好用的 API 文档生成框架,真香
-
网页转成pdf文件的经验分享 网页转成pdf文件的经验分享怎么弄
-
C++ std::vector 简介
-
飞牛OS入门安装遇到问题,如何解决?
-
系统C盘清理:微信PC端文件清理,扩大C盘可用空间步骤
-
10款高性能NAS丨双十一必看,轻松搞定虚拟机、Docker、软路由
-
- 最近发表
- 标签列表
-
- python判断字典是否为空 (50)
- crontab每周一执行 (48)
- aes和des区别 (43)
- bash脚本和shell脚本的区别 (35)
- canvas库 (33)
- dataframe筛选满足条件的行 (35)
- gitlab日志 (33)
- lua xpcall (36)
- blob转json (33)
- python判断是否在列表中 (34)
- python html转pdf (36)
- 安装指定版本npm (37)
- idea搜索jar包内容 (33)
- css鼠标悬停出现隐藏的文字 (34)
- linux nacos启动命令 (33)
- gitlab 日志 (36)
- adb pull (37)
- python判断元素在不在列表里 (34)
- python 字典删除元素 (34)
- vscode切换git分支 (35)
- python bytes转16进制 (35)
- grep前后几行 (34)
- hashmap转list (35)
- c++ 字符串查找 (35)
- mysql刷新权限 (34)