首页 / Spring Boot 入门教程 / 核心注解速查

Spring Boot 入门教程

核心注解速查

本教程共 48 篇 · 第 9 篇 · 更新于 2026-08-13 · 约 4 分钟阅读

注解@RestController依赖注入@Value注解速查Spring MVC

本节目标:把最常用的 Spring / Spring Boot 注解集中过一遍——含义、用法、常见坑,当字典查。

注解是贴在代码上的「元数据」:不改逻辑,只加说明。Spring 读注解来决定行为。前 8 章零散出现过不少,这章按用途归类,做速查。

组件与配置

注解作用章节
@SpringBootApplication主类三合一:自动配置 + 组件扫描 + 配置4、6
@Component / @Service / @Repository / @Controller声明 Bean7
@Configuration配置类,里面放 @Bean 方法7
@Bean手动声明一个 Bean7

Web 注解:写接口的三件套

@RestController@Controller + @ResponseBody 的合体。返回的对象直接序列化成 JSON 写进响应体,不经过视图解析。写 REST 接口,控制器一律用它。用 @Controller 也能配 @ResponseBody 返回 JSON,但多写一个注解,没必要。

先定义一个数据类,后面例子都用它:

package com.example.demo;

public record User(Long id, String name) {
}
package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @GetMapping("/users/{id}")
    public User getUser(@PathVariable Long id) {
        // 根据 id 查用户
        return new User(id, "码上学");
    }
}

@RequestMapping 是通用映射,能配路径和方法。标在类上,给整个控制器加路径前缀;标在方法上,指定具体接口。它有五个快捷注解,日常优先用快捷版:

快捷注解等价写法用途
@GetMapping@RequestMapping(method = RequestMethod.GET)查询
@PostMapping@RequestMapping(method = RequestMethod.POST)新增
@PutMapping@RequestMapping(method = RequestMethod.PUT)整体更新
@PatchMapping@RequestMapping(method = RequestMethod.PATCH)局部更新
@DeleteMapping@RequestMapping(method = RequestMethod.DELETE)删除

参数绑定注解,一个接口全用上:

package com.example.demo;

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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;

@RestController
public class UserController {

    // GET /api/users?page=1&size=20
    @GetMapping("/api/users")
    public List<User> list(@RequestParam(defaultValue = "1") int page,
                           @RequestParam(defaultValue = "20") int size) {
        return List.of();
    }

    // GET /api/users/42
    @GetMapping("/api/users/{id}")
    public User get(@PathVariable Long id) {
        return new User(id, "码上学");
    }

    // POST /api/users,body 是 JSON
    @PostMapping("/api/users")
    public User create(@RequestBody User user) {
        return user;
    }
}

对照表:

注解绑定的数据例子
@PathVariableURL 路径变量/users/{id} 里的 id
@RequestParam查询参数 / 表单字段?page=1 里的 page
@RequestBody请求体 JSON,自动反序列化POST 的 body
@ModelAttribute表单绑定到对象传统 MVC 表单提交
Tip

@RequestParamdefaultValue 是常见写法。参数可缺省,接口更稳。它默认必填,required = false 也能放宽,但通常用 defaultValue 就够了。

装配注解:依赖怎么进来

@Autowired 按类型自动注入。字段、setter、构造器都能标:

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {

    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }
}

第 7 章说过:单构造器不用标 @Autowired,多构造器才需要它指定「用哪个」。字段注入能写但别写——测试难、依赖不可见。

同类型多个 Bean 时,@Autowired 会迷茫,报 NoUniqueBeanDefinitionException。两个注解救场。

@Qualifier 点名要哪个:

package com.example.demo;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class OrderService {

    private final MessageService messageService;

    public OrderService(@Qualifier("smsMessageService") MessageService messageService) {
        this.messageService = messageService;
    }
}

@Primary 指定默认人选——不点名时优先用它:

package com.example.demo;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

@Configuration
public class MessageConfig {

    @Bean
    @Primary
    public MessageService emailMessageService() {
        return new EmailMessageService();
    }

    @Bean
    public MessageService smsMessageService() {
        return new SmsMessageService();
    }
}
Tip

面试高频:@Autowired 默认按类型装配;类型有多个,按名字找;再不行,配合 @Qualifier@Primary

配置值:@Value

@Value 把配置值注入字段。带默认值的写法,属性缺失不报错:

package com.example.demo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class MessageService {

    @Value("${app.message:默认消息}")
    private String message;

    public String getMessage() {
        return message;
    }
}

app.messageapplication.yml 里配:

app:
  message: "你好,Spring Boot"

@Value 的值里还能写 SpEL 表达式,比如 @Value("#{systemProperties['user.name']}") 取系统属性。项目里用得少,知道有这回事就行。

Note

@Value 适合单个零散值。多个相关属性(一组配置)用 @ConfigurationProperties 更合适,第 11 章细讲。两者不是替代关系,各有场景。

其他高频注解

注解作用
@Scope("prototype")改 Bean 作用域,默认单例
@Lazy懒加载,首次使用时才创建 Bean
@Transactional方法 / 类开启事务,异常自动回滚(第 26 章展开)
@Import手动导入其他配置类
@Profile指定 Profile 下才生效(第 13 章展开)
@EnableCaching / @EnableAsync开启缓存 / 异步支持

@ResponseStatus 指定返回的 HTTP 状态码,标在异常类上最常用:

package com.example.demo;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@ResponseStatus(HttpStatus.NOT_FOUND)
public class UserNotFoundException extends RuntimeException {
}

控制器里 throw new UserNotFoundException(),响应就是 404,不用写 catch。

@ComponentScan 默认扫主类所在包。需要扩大范围时,用 basePackages 指定额外包:

@ComponentScan(basePackages = {"com.example.demo", "com.example.common"})

一般用不上——主类放顶层包,默认扫描就够。

三个常见坑

注解加错位置。 @Bean 只能放在 @Configuration 类的方法上;@GetMapping 只对控制器方法有意义。注解不是贴纸,位置错了 Spring 不认。

包扫描不到。 Bean 类不在主类所在包的子包里,注入时报 NoSuchBeanDefinitionException。先查包结构,再看扫描范围。

同名 Bean 冲突。 两个 @Bean 方法返回同类型,注入时容器不知道选谁。用 @Primary 定默认、@Qualifier 点名,或者去掉多余那个。

小结

  • 写接口:@RestController + 方法级快捷映射 + 参数绑定三件套。
  • 注入依赖:构造器注入为主,@Qualifier / @Primary 解决多 Bean 冲突。
  • 读配置:单值用 @Value,一组用 @ConfigurationProperties
  • 其他注解按需查表,用到再深挖。