SpringBoot 常用注解详细解析

 更新时间:2026年02月27日 10:46:15   作者:莫寒清  
Spring Boot常用注解总结包括启动类、依赖注入、配置管理、Web开发、条件装配、功能启用及其他常用注解,本文介绍SpringBoot 常用注解详细解析,感兴趣的朋友跟随小编一起看看吧

一句话总结

  • 整体记忆:启动靠 @SpringBootApplication,IOC 靠组件注解 + @Autowired,配置靠 @Value/@ConfigurationProperties,Web 层靠 @RestController + 各种 @xxxMapping,扩展能力靠 @Enable 系列,细节控制靠条件装配和事务、校验等注解。
  • 面试常问:
    • @SpringBootApplication 里面包含了什么?
    • @RestController@Controller 的区别?
    • @Autowired@Resource 的区别?
    • @ConfigurationProperties@Value 的区别及使用场景?
    • 自动装配是如何依赖 @ConditionalOnXXX 系列的?

详细解析

一、启动类注解

Spring Boot 应用的入口类需要通过注解声明启动逻辑,一个注解顶三个传统配置

注解作用
@SpringBootApplication启动类核心注解,是以下三个注解的组合(约定优于配置的入口):
1. @SpringBootConfiguration:声明当前类是配置类(等价于 @Configuration);
2. @EnableAutoConfiguration:开启自动配置(让 Spring Boot 自动加载符合条件的 Bean);
3. @ComponentScan:默认扫描当前包及子包下的 @Component 及其衍生注解(如 @Service)标记的类,注册为 Bean。

面试点小结

  • 高频问题:如果不想让某些包被扫描,或者想自定义扫描路径,怎么做?—— 使用 @SpringBootApplication(scanBasePackages = "...") 或者在 @ComponentScan 中单独配置。

代码示例:自定义扫描包路径

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
// 方式一:直接在 @SpringBootApplication 上指定扫描包
@SpringBootApplication(scanBasePackages = {
        "com.example.service",
        "com.example.web"
})
public class CustomScanApplication {
    public static void main(String[] args) {
        SpringApplication.run(CustomScanApplication.class, args);
    }
}
// 方式二:配合 @ComponentScan 单独配置(等价写法)
@SpringBootApplication
@ComponentScan(basePackages = {
        "com.example.service",
        "com.example.web"
})
class AnotherApplication {
}

代码示例:启动类写法

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

二、依赖注入(IOC)注解

Spring 的核心是 IOC(控制反转),常见问题就是:谁是 Bean?Bean 如何注入?注入冲突时怎么解决?

1. 声明 Bean 的注解(标记类/方法为可被 IOC 管理的组件)

注解作用
@Component通用组件标记(所有被 IOC 管理的类的基础注解)。
@Service标记业务层(Service 层)组件(等价于@Component,语义更明确)。
@Controller标记 Web 控制器组件(等价于@Component,语义更明确)。
@Repository标记数据访问层(DAO 层)组件(等价于@Component,语义更明确,Spring 会自动将特定数据访问异常转换为 Spring 统一异常层次)。
@Configuration标记配置类(通常用于声明@Bean方法),等价于传统 Spring 的 XML 配置文件。
@Bean声明一个 Bean(标注在方法上,方法返回值会被注册到 IOC 容器)。

代码示例:分层组件与配置类

import org.springframework.stereotype.Service;
import org.springframework.stereotype.Repository;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Service
public class UserService {
    public String getUserName() {
        return "Tom";
    }
}
@Repository
public class UserRepository {
    // 模拟持久层
}
@Configuration
public class AppConfig {
    @Bean
    public String commonBean() {
        return "I am a bean";
    }
}

易混点

  • @Component/@Service/@Controller/@Repository 功能几乎相同,主要是语义和分层清晰,方便维护和 AOP 等按层次织入
  • @Configuration 的类中方法如果标了 @Bean默认是单例且有 CGLIB 增强,同一个 @Bean 方法多次调用只会返回同一个 Bean。

这句话是什么意思?

  • Spring 会为标注了 @Configuration 的类创建一个 CGLIB 代理子类,拦截对 @Bean 方法的调用。
  • 无论是在容器内部互相调用,还是你手动拿到配置类实例去调用 @Bean 方法,最终都会从 IOC 容器中取同一个单例 Bean,而不是每次 new 一个。

什么是 CGLIB?

  • CGLIB(Code Generation Library)是一个基于 字节码增强 的类库,可以在运行时为某个类生成一个子类,并通过方法拦截实现 AOP、代理等功能。
  • 和基于 JDK 的动态代理只支持接口不同,CGLIB 可以代理没有实现接口的普通类,这也是 Spring 能够增强 @Configuration 类、普通 Bean 类的关键手段之一。

代码示例:@Configuration + @Bean 的单例与代理行为

@Configuration
public class BeanConfig {
    @Bean
    public User user() {
        return new User();
    }
    @Bean
    public List<User> userList() {
        // 虽然看起来调用了两次 user(),但因为有 CGLIB 代理,这里返回的是同一个单例 Bean
        return Arrays.asList(user(), user());
    }
}

扩展:如果这里的类不是 @Configuration 而只是 @Component,那么 user() 方法不会被代理拦截,每次调用都会 new 一个对象,userList 中就会有两个不同的 User 实例。

2. 注入 Bean 的注解(从 IOC 容器中获取 Bean)

注解作用
@AutowiredSpring 原生注入注解(默认按类型注入,可配合 @Qualifier 按名称指定,支持构造器/Setter/字段注入)。
@ResourceJSR-250 标准注解(默认按名称注入,无名称时按类型注入,来自 jakarta.annotation / javax.annotation)。
@Qualifier配合@Autowired使用,指定注入的 Bean 名称(解决同类型多 Bean 的歧义问题)。
@Primary标记同类型 Bean 中的“主选” Bean(当@Autowired遇到多 Bean 时优先选择它)。
@Lazy标记 Bean 为延迟加载(默认 IOC 启动时创建 Bean,@Lazy会在首次使用时创建)。
@Scope指定 Bean 的作用域(如 singleton(默认单例)、prototype(多例)、request(HTTP 请求作用域)等)。

面试高频:@Autowired vs @Resource

  • 来源不同@Autowired 来自 Spring,@Resource 来自 JSR 规范(更标准化)。
  • 装配策略不同@Autowired 先按类型匹配,再结合 @Qualifier@Resource 默认按名称,找不到再按类型。
  • 推荐实践:实际开发中更常见的是 @Autowired + 构造器注入(更利于单元测试、不可变设计)。

代码示例:@Autowired、@Qualifier、@Primary

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
public interface MessageService {
    String send();
}
@Component("emailService")
@Primary // 同类型多个 Bean 时,优先注入
class EmailService implements MessageService {
    @Override
    public String send() {
        return "send email";
    }
}
@Component("smsService")
class SmsService implements MessageService {
    @Override
    public String send() {
        return "send sms";
    }
}
@Component
class MessageController {
    // 指定注入 smsService,而不是默认的 @Primary emailService
    @Autowired
    @Qualifier("smsService")
    private MessageService messageService;
}

三、配置管理注解

Spring Boot 通过 application.properties / application.yml 管理配置,常见问题是:简单配置用什么?复杂配置用什么?如何支持类型安全?

注解作用
@Value读取单个配置属性(支持 SpEL 表达式),如 @Value("${server.port}"),适合零散简单配置
@ConfigurationProperties批量绑定配置到 Java 对象(适用于复杂配置,如 prefix="spring.datasource" 绑定一组属性,支持 JSR303 校验)。
@PropertySource加载自定义配置文件(默认加载 application.properties,可用此注解加载其他文件,如 @PropertySource("classpath:my-config.properties"))。
@EnableConfigurationProperties启用 @ConfigurationProperties 标记的类(通常配合 @Configuration 或在启动类上使用)。

面试高频:@ConfigurationProperties vs @Value

  • @Value:适合零散、简单、单个字段的配置读取,不支持批量映射和校验。
  • @ConfigurationProperties:适合成组配置、需要类型安全和校验的场景,推荐用于中大型项目。

代码示例:@Value 与 @ConfigurationProperties 读取配置

// application.yml
app:
  name: demo-app
  version: v1.0
server:
  port: 8081
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {
    private String name;
    private String version;
    // getter / setter 省略
}
@Component
public class ConfigDemo {
    // 读取单个配置
    @Value("${server.port}")
    private int serverPort;
}

四、Web 开发注解

Spring Boot 内置 Spring MVC,以下注解用于处理 HTTP 请求、响应和参数,是Controller 层面试的重灾区

1. 控制器与请求映射

注解作用
@RestControllerRESTful 控制器(等价于 @Controller + @ResponseBody,返回数据直接序列化为 JSON/JSONP/XML 等)。
@Controller传统 MVC 控制器(返回视图名或配合 @ResponseBody 返回数据)。
@RequestMapping通用请求映射(可标记类或方法,指定 URL 路径、请求方法等,如 @RequestMapping("/user"))。
@GetMapping@RequestMapping(method = RequestMethod.GET) 的简写(处理 GET 请求)。
@PostMapping处理 POST 请求(类似@GetMapping)。
@PutMapping处理 PUT 请求。
@DeleteMapping处理 DELETE 请求。

代码示例:@RestController 与请求映射

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/users")
public class UserController {
    @GetMapping("/{id}")
    public String getUser(@PathVariable Long id) {
        return "user id = " + id;
    }
    @PostMapping
    public User createUser(@RequestBody User user) {
        // 简化处理:直接返回请求体
        return user;
    }
}

易错点

  • @RestController 已经包含 @ResponseBody,不要再在方法上重复标注 @ResponseBody
  • 类上 @RequestMapping + 方法上 @GetMapping,最终路径是类路径 + 方法路径拼接

2. 请求参数与响应

注解作用
@RequestBody将请求体(如 JSON)反序列化为 Java 对象(用于 POST/PUT 等带请求体的请求)。
@RequestParam读取 URL 中的查询参数(如 @RequestParam("username") String name),可设置默认值、是否必填。
@PathVariable读取 URL 路径中的占位符(如 @GetMapping("/user/{id}") 配合 @PathVariable("id") Long userId)。
@ResponseBody将返回值序列化为 JSON/XML(通常配合@Controller使用,@RestController已内置此注解)。
@ResponseStatus设置响应状态码(如@ResponseStatus(HttpStatus.CREATED)返回 201 状态码)。
@CrossOrigin解决跨域问题(标记类或方法,指定允许的源、方法等,常与前后端分离一起使用)。

面试常问

  • @RequestBody@RequestParam 的区别?—— 一个读 请求体,一个读 查询参数/表单字段
  • @PathVariable@RequestParam 的典型使用场景?—— 资源 ID 通常用路径变量,筛选条件用查询参数。

代码示例:@RequestParam、@PathVariable、@CrossOrigin

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
@CrossOrigin(origins = "http://localhost:3000")
public class DemoController {
    // GET /hello?name=Tom
    @GetMapping("/hello")
    public String hello(@RequestParam String name) {
        return "hello " + name;
    }
    // GET /order/100
    @GetMapping("/order/{id}")
    public String getOrder(@PathVariable("id") Long orderId) {
        return "order id = " + orderId;
    }
}

五、条件装配注解(自动配置核心)

Spring Boot 的自动配置本质上就是:根据条件装配不同的 Bean,因此 @ConditionalOnXXX 是理解自动配置的关键。

注解作用
@Conditional通用条件装配(需自定义 Condition 接口实现,很少直接在业务代码中使用,多见于基础框架)。
@ConditionalOnClass当类路径中存在指定类时,才加载当前 Bean(如 @ConditionalOnClass(DataSource.class))。
@ConditionalOnMissingClass当类路径中不存在指定类时,才加载当前 Bean。
@ConditionalOnBean当 IOC 容器中存在指定 Bean 时,才加载当前 Bean。
@ConditionalOnMissingBean当 IOC 容器中不存在指定 Bean 时,才加载当前 Bean(用于提供默认实现,典型场景:允许用户自定义覆盖)。
@ConditionalOnProperty当配置文件中存在指定属性且值符合条件时,才加载当前 Bean(如 @ConditionalOnProperty(prefix="redis", name="enable", havingValue="true"))。
@ConditionalOnResource当类路径中存在指定资源(如文件)时,才加载当前 Bean。

代码示例:@ConditionalOnProperty 控制功能开关

// application.yml
feature:
  sms:
    enabled: true
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
@Component
@ConditionalOnProperty(prefix = "feature.sms", name = "enabled", havingValue = "true")
public class SmsSender {
    // 只有当 feature.sms.enabled = true 时才会装配
}

理解自动配置的一句话:自动配置 = 一堆 @Configuration 类 + 各种 @ConditionalOnXXX 条件判断 + SpringFactoriesLoader 加载机制。

六、功能启用注解(@Enable 系列)

以下注解用于开启 Spring Boot 的扩展功能,本质上是导入对应配置类,再配合条件装配完成 Bean 注册。

注解作用
@EnableAutoConfiguration开启自动配置(@SpringBootApplication已包含此注解)。
@EnableScheduling开启任务调度(支持@Scheduled注解)。
@EnableAsync开启异步方法支持(配合@Async使用)。
@EnableCaching开启缓存支持(配合@Cacheable、@CachePut等注解)。
@EnableTransactionManagement开启声明式事务支持(配合@Transactional使用)。
@EnableFeignClients开启 Feign 客户端(用于微服务远程调用)。

代码示例:@EnableScheduling + @Scheduled 定时任务

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@SpringBootApplication
@EnableScheduling
public class ScheduleApplication {
    public static void main(String[] args) {
        SpringApplication.run(ScheduleApplication.class, args);
    }
}
@Component
class TaskJob {
    // 每 5 秒执行一次
    @Scheduled(fixedRate = 5000)
    public void run() {
        System.out.println("task running...");
    }
}

七、其他常用注解

注解作用
@Transactional声明事务(标记方法或类,支持事务隔离级别、传播行为等配置,是 Spring 事务的核心入口)。
@Valid/@Validated开启参数校验(配合 jakarta.validation 约束注解,如 @NotBlank@Max)。
@Profile标记 Bean 仅在指定环境(如 devprod)中生效(通过 spring.profiles.active 配置激活)。
@Import手动导入其他配置类或 Bean(类似 XML 中的 <import>,可实现简易模块组合)。
@Aspect标记 AOP 切面类(配合 @Pointcut@Before 等实现切面编程)。

常见面试点简要说明

  • @Transactional
    • 默认只对 RuntimeException 及其子类 回滚,如需对受检异常回滚要显式配置 rollbackFor
    • 作用在接口/类/方法上,以方法级别优先;注意自调用导致事务失效的问题。
  • @Profile
    • 常与多数据源、多环境配置一起使用;可以用 @Profile("dev") 标记开发环境专用 Bean。
    • 生产环境通常通过 JVM 参数或配置中心设置 spring.profiles.active

代码示例:@Transactional 声明式事务

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class OrderService {
    @Transactional(rollbackFor = Exception.class)
    public void createOrder() {
        // 1. 插入订单表
        // 2. 扣减库存
        // 3. 发生异常时整体回滚
    }
}

代码示例:@Valid 参数校验

// 引入依赖(通常在 pom.xml 中):
// spring-boot-starter-validation
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Max;
public class UserDTO {
    @NotBlank(message = "用户名不能为空")
    private String name;
    @Max(value = 120, message = "年龄不能超过 120")
    private int age;
    // getter / setter 省略
}
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ValidateController {
    @PostMapping("/users")
    public String create(@Valid @RequestBody UserDTO user) {
        return "ok";
    }
}

到此这篇关于SpringBoot 常用注解的文章就介绍到这了,更多相关springboot 常用注解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java SPEL表达式注入漏洞原理解析

    Java SPEL表达式注入漏洞原理解析

    SpEL简称Spring表达式语言,在Spring 3中引入,SpEL能在运行时构建复杂表达式、存取对象图属性、对象方法调用等等,可以与基于XML和基于注解的Spring配置还有bean定义一起使用,本文给大家介绍Java SPEL表达式注入漏洞原理研究,感兴趣的朋友一起看看吧
    2023-10-10
  • Shiro:自定义Realm实现权限管理方式

    Shiro:自定义Realm实现权限管理方式

    这篇文章主要介绍了Shiro:自定义Realm实现权限管理方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • springboot整合flowable框架入门步骤

    springboot整合flowable框架入门步骤

    最近工作中有用到工作流的开发,引入了flowable工作流框架,在此记录一下springboot整合flowable工作流框架的过程,感兴趣的朋友一起看看吧
    2022-04-04
  • Mybatisplus如何存储List、Map

    Mybatisplus如何存储List、Map

    这篇文章主要介绍了Mybatisplus如何存储List、Map问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • 如何自定义MyBatis拦截器更改表名

    如何自定义MyBatis拦截器更改表名

    自定义MyBatis拦截器可以在方法执行前后插入自己的逻辑,这非常有利于扩展和定制 MyBatis 的功能,本篇文章实现自定义一个拦截器去改变要插入或者查询的数据源 ,需要的朋友可以参考下
    2023-10-10
  • Mybatis插入Oracle数据库日期型数据过程解析

    Mybatis插入Oracle数据库日期型数据过程解析

    这篇文章主要介绍了Mybatis插入Oracle数据库日期型数据过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • Java程序包不存在的两种解决方法

    Java程序包不存在的两种解决方法

    有时候我们在导入程序之后,系统会给出错误提示:Java:程序包xxxx不存在,本文主要介绍了Java程序包不存在的两种解决方法,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02
  • 使用fileupload组件实现文件上传功能

    使用fileupload组件实现文件上传功能

    这篇文章主要为大家详细介绍了使用fileupload实现文件上传功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • 基于SpringAOP+Caffeine实现本地缓存的实例代码

    基于SpringAOP+Caffeine实现本地缓存的实例代码

    公司想对一些不经常变动的数据做一些本地缓存,我们使用AOP+Caffeine来实现,所以本文给大家介绍了
    基于SpringAOP+Caffeine实现本地缓存的实例,文中有详细的代码供大家参考,需要的朋友可以参考下
    2024-03-03
  • java八大经典书籍 你看过几本?

    java八大经典书籍 你看过几本?

    java八大经典书籍,你看过几本?本文为大家分享了java学习书单,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01

最新评论