Spring框架注解及使用详情
Spring框架注解及使用
Bean声明与装配注解
@Component - 通用组件注解
这个注解是Spring通用的组件注解,它是(@Service,@Repository,@Controller)的父注解,用于标识组件并交给Spring管理。
使用场景:当你的类不属于任何特定分层(如工具类、通用组件)时使用。
举例:
1 | import org.springframework.stereotype.Component; |
@Service - 服务层组件
专门用于逻辑业务层(Service层)的注解,本质是@Component的别名,但是更加具有语义化(标识用于Service层)
使用场景:所有处理业务逻辑的类。
附加价值:Spring 对 @Service 有特殊的异常转换支持(如将数据层异常转为 Spring 统一的 DataAccessException)。
举例:
1 | import org.springframework.stereotype.Service; |
@Repository - 数据访问层组件
专门用于标识数据访问层(DAO层或者Repository层)的标识注解,本质上还是@Component注解,具有特定的语义(专门用于标识数据访问层)
使用场景:操作数据库的类(UserDao、OrderRepository等)
附加价值:Spring 会自动将 @Repository 标注的类中抛出的原生持久化异常(如 JDBC、MyBatis 异常)转换为 Spring 统一的 DataAccessException 异常体系。
举例:
1 | import org.springframework.stereotype.Repository; |
@Controller - Web 控制器组件
专门用于Web层(控制层)的注解,标识一个类是Spring MVC的控制器,用于处理Http请求。
核心能力:配合 @RequestMapping 等注解映射请求路径,默认返回视图(如 JSP/HTML)。
使用场景:传统 MVC 开发中,需要返回页面的控制器。
举例:
1 | import org.springframework.stereotype.Controller; |
@RestController - REST 控制器(包含 @Controller 和 @ResponseBody)
作用:专门用于开发 RESTful API 的控制器注解,是 @Controller + @ResponseBody 的组合注解。
核心能力:所有方法的返回值都会被自动序列化为 JSON/XML 格式,直接写入 HTTP 响应体,而非返回视图。
使用场景:前后端分离项目中,提供接口(返回 JSON 数据)的控制器。
举例:
1 | import org.springframework.web.bind.annotation.GetMapping; |
@Configuration - 配置类
作用:标识一个类是 Spring 的配置类,替代传统的 XML 配置文件(如 applicationContext.xml)。
核心能力:配置类中可以通过 @Bean 注解声明自定义的 Bean,也可以导入其他配置类、扫描组件等。
使用场景:需要手动配置 Bean(如第三方组件、自定义对象)时使用。
举例:
1 | import org.springframework.context.annotation.Configuration; |
@Bean - 声明 Bean
作用:用于 @Configuration 类的方法上,手动声明一个 Bean,Spring 会将该方法的返回值纳入 IoC 容器管理。
核心能力:可以自定义 Bean 的创建逻辑(如初始化参数、依赖注入),Bean 的默认名称是方法名,也可通过 name/value 属性指定。
使用场景:创建第三方类的实例(如 RedisTemplate、DataSource)、自定义复杂对象的实例时。
举例:
1 | import org.springframework.context.annotation.Bean; |
@Scope - 指定 Bean 作用域
作用:指定 Bean 的作用域(生命周期范围),控制 Spring 创建 Bean 实例的数量和时机。
常用取值:
| 取值 | 含义 |
|---|---|
| singleton | 单例(默认):IoC 容器中只有一个 Bean 实例,全局共享 |
| prototype | 原型:每次获取 Bean 时都创建新实例 |
| request | Web 环境:每个 HTTP 请求创建一个新实例 |
| session | Web 环境:每个 HTTP Session 创建一个新实例 |
| application | Web 环境:整个 Web 应用(ServletContext)共享一个实例 |
- singleton (单例) —— 默认规则
- 含义: 在整个 Spring 容器中,这个 Bean 只有一个。
- 通俗理解: 就像共享单车。全城(容器)只有这一辆编号为 001 的车,谁扫码(请求 Bean)骑的都是这一辆。你改了车铃,下一个人骑的时候铃也是改过的。
- 使用场景: 绝大多数无状态的类(如 @Service、@Controller、@Repository)。
- prototype (原型) —— 每次都新做
- 含义: 每次获取(通过 getBean() 或注入)时,Spring 都会重新创建一个全新的实例。
- 通俗理解: 就像外卖奶茶店。每个人下单(请求 Bean),店里都会现场现做一杯全新的给你,你喝你的,他喝他的,互不影响。
- 使用场景: 含有多线程操作或带有状态(成员变量会变)的类。
- Web 环境专属作用域
注意: 下面这三个必须在 Web 项目(Spring MVC/WebFlux)中才有效。
- request (请求)
- 含义: 每个 HTTP 请求都会创建一个新的 Bean,请求结束,Bean 销毁。
- 通俗理解: 就像餐厅的桌布。客人 A 进店吃饭(发起请求),铺一块新桌布;客人 A 吃完走了,桌布撤掉。客人 B 来了,再铺一块新的。
- session (会话)
- 含义: 在同一个 HTTP Session 中,Bean 是共享的。
- 通俗理解: 就像酒店的房卡。你在酒店住的这几天(同一个 Session),无论你进出房间多少次,用的都是同一张卡。直到你退房,这张卡才失效。
- application (应用)
- 含义: 整个 Web 应用(ServletContext)生命周期内只有一个。
- 通俗理解: 就像酒店的大堂经理。只要酒店开门营业,大堂经理就在那里,所有住客面对的都是同一个大堂经理。
举例:
1 | import org.springframework.context.annotation.Bean; |
@Lazy - 延迟初始化
作用:指定 Bean 为延迟初始化,即 Bean 不会在 Spring 容器启动时创建,而是在第一次被使用时(如 getBean()、依赖注入)才创建。
适用场景:
- 单例 Bean(默认立即初始化)想延迟创建,减少容器启动时间;
- 解决循环依赖的部分场景;
- 资源密集型 Bean(如大对象),避免启动时占用资源。
举例:
1 | import org.springframework.context.annotation.Bean; |
@Primary - 首选 Bean
作用:当存在多个同类型的 Bean 时,指定 “首选 Bean”,Spring 自动注入时会优先选择标注了 @Primary 的 Bean。
使用场景:解决 “同类型多个 Bean 注入时的歧义问题”。
举例:
1 | import org.springframework.context.annotation.Bean; |
@DependsOn - 依赖关系
作用:强制指定 Bean 的初始化顺序,确保标注 @DependsOn 的 Bean 被初始化前,其依赖的 Bean 已经先初始化完成。
适用场景:某些 Bean 的初始化依赖其他 Bean 先完成(如 A Bean 需要读取 B Bean 初始化的配置)。
举例:
1 | import org.springframework.context.annotation.Bean; |
依赖注入
@Autowired - 自动装配
Spring 框架原生注解,用于自动注入依赖的 Bean,默认按照 类型(Type) 匹配 IoC 容器中的 Bean,完成依赖注入。
注入位置:可标注在构造器、字段、setter 方法、普通方法上;
默认规则:默认要求注入的 Bean 必须存在(否则抛 NoSuchBeanDefinitionException),可通过 required = false 关闭强制检查;
优先级:
- 先按类型匹配(如注入 UserService 类型,找容器中所有 UserService 类型的 Bean);
- 若找到多个同类型 Bean,会尝试按字段名 / 方法参数名匹配 Bean 名称;
- 若仍匹配失败,需配合
@Qualifier指定 Bean 名称。
举例:
1 | import org.springframework.beans.factory.annotation.Autowired; |
@Qualifier - 指定 Bean 名称
配合 @Autowired 使用,解决同类型多个 Bean 注入的歧义问题,明确指定要注入的 Bean 名称(而非按类型 / 字段名匹配)。
使用场景:当 IoC 容器中有多个同类型的 Bean 时(比如有两个 DataSource 类型的 Bean:primaryDataSource 和 secondaryDataSource),仅用 @Autowired 会报错,需用 @Qualifier 指定名称。
举例:
1 | import org.springframework.beans.factory.annotation.Autowired; |
@Value - 注入属性值
核心作用:用于注入外部配置的属性值(如 application.properties/application.yml 中的配置、系统环境变量、字面量等),支持 SpEL(Spring 表达式语言)。
常用注入场景
| 注入类型 | 示例写法 | 说明 |
|---|---|---|
| 字面量 | @Value(“hello”) | 直接注入字符串 “hello” |
| 配置文件属性 | @Value(“${server.port}”) | 注入配置文件中 server.port 的值 |
| 系统环境变量 | @Value(“${JAVA_HOME}”) | 注入系统环境变量 JAVA_HOME |
| SpEL | 表达式 @Value(“#{100 + 20}”) | 执行表达式,注入 120 |
| 默认值 | @Value(“${app.name:默认名称}”) | 配置不存在时用默认值 |
举例:
1 | import org.springframework.beans.factory.annotation.Value; |
@Resource - JSR-250 注解
核心作用:JSR-250 规范定义的依赖注入注解(非 Spring 原生),用于注入 Bean,默认按 名称(Name) 匹配,名称匹配失败时按 类型(Type) 匹配。
与 @Autowired 的核心区别
| 特性 | @Autowired | @Resource |
|---|---|---|
| 所属规范 | Spring 原生 | JSR-250(Java 标准) |
| 默认匹配规则 | 按类型 → 按名称 | 按名称 → 按类型 |
| 支持指定名称 | 需配合 @Qualifier | 直接用 name 属性(@Resource(name=”xxx”)) |
| 支持required=false | 支持(@Autowired(required=false)) | 不支持(找不到 Bean 直接报错) |
| 注入位置 | 构造器、字段、方法 | 字段、setter 方法(不支持构造器) |
举例:
1 | import javax.annotation.Resource; |
@Inject - JSR-330 注解
核心作用:JSR-330 规范定义的依赖注入注解(Java EE 标准),功能与 @Autowired 类似,默认按 类型 匹配,需配合 @Named 指定 Bean 名称(替代 @Qualifier)。
核心特点
- 无 required 属性,若找不到 Bean 直接抛异常;
- 需导入额外依赖(Spring 已内置,无需手动加);
- 更符合 Java 标准,可跨框架使用(如 Guice 也支持)。
与 @Autowired 的对比
| 特性 | @Autowired | @Inject |
|---|---|---|
| 所属规范 | Spring 原生 | JSR-330(Java 标准) |
| 默认匹配规则 | 按类型 | 按类型 |
| 指定 Bean 名称 | 配合 @Qualifier | 配合 @Named |
| required 特性 | 支持 required=false | 不支持(强制要求 Bean 存在) |
| 依赖 | 无需额外依赖 | Spring 已内置,无需手动导入 |
举例:
1 | import javax.inject.Inject; |







