外观
五、关键注解速查(Java/Spring Boot)
Java 注解(Annotation)就是代码上面那个
@开头的东西。 如果你写过 TypeScript 装饰器(@decorator)或 Python 装饰器(@wrapper),你会觉得很眼熟。 不同的是,Java 注解通常由框架在运行时读取并执行特定逻辑。
5.1 控制器层注解
这些注解是你在 controller/ 目录下最常见的:
java
@RestController // 标记这个类是一个 REST API 控制器
// 前端类比:export default 一个 API handler 文件
@RequestMapping("/v1/user") // 给这个控制器设置 URL 前缀
// 前端类比:app.use('/v1/user', router)
@GetMapping("/profile") // 处理 GET /v1/user/profile
@PostMapping("/login") // 处理 POST /v1/user/login
@PutMapping("/profile") // 处理 PUT /v1/user/profile
@DeleteMapping("/{id}") // 处理 DELETE /v1/user/{id}完整示例
java
@RestController // 这是一个 API 控制器
@RequestMapping("/v1/user") // 前缀 /v1/user
@Slf4j // 自动生成 log 对象(后面讲)
public class UserController {
@Autowired // 注入 service(后面讲)
private UserService userService;
@PostMapping("/login") // POST /v1/user/login
public RtData<LoginResponse> login(
@RequestBody @Validated LoginDto dto // 从请求体读取 JSON
) {
return RtData.ok(userService.login(dto));
}
@GetMapping("/profile") // GET /v1/user/profile
public RtData<UserProfile> getProfile(
@RequestHeader("uid") Long uid // 从请求头读取 uid
) {
return RtData.ok(userService.getProfile(uid));
}
}5.2 参数绑定注解
这些注解告诉框架"从请求的哪个位置读取参数":
java
@RequestBody LoginDto dto // 读取请求体 JSON 并映射为对象
// 前端类比:const dto = req.body
@RequestHeader("uid") Long uid // 读取请求头
// 前端类比:const uid = req.headers['uid']
@PathVariable("id") String id // 读取路径参数
// 前端类比:const { id } = req.params
// URL: /user/{id} → /user/123
@RequestParam("page") int page // 读取查询参数
// 前端类比:const page = req.query.page
// URL: /users?page=1
@Validated // 自动校验参数(配合 DTO 中的校验注解)
// 前端类比:zod.parse(dto) 或 yup.validate(dto)DTO 校验注解示例
java
public class LoginDto {
@NotBlank(message = "手机号不能为空") // 非空校验
private String phone;
@NotBlank(message = "验证码不能为空")
@Size(min = 4, max = 6) // 长度校验
private String verifyCode;
}💡 前端类比:这就是 Java 版的 zod schema:
typescriptconst LoginSchema = z.object({ phone: z.string().min(1, "手机号不能为空"), verifyCode: z.string().min(4).max(6), })
5.3 业务层注解
java
@Service // 标记为业务逻辑类
// 前端类比:定义一个 service 模块
@Repository // 标记为数据访问类
// 前端类比:定义一个 data-access 模块
@Component // 通用组件标记,Spring 会自动创建实例并管理
// 前端类比:通过 provide() 注册一个全局服务
@Autowired // 自动注入依赖
// 前端类比:const service = useContext(ServiceContext)
// 或 Vue 的 inject('service')
@Resource // 功能同 @Autowired,但按名称注入
// 当有多个同类型 Bean 时用名称区分依赖注入原理(重要概念)
text
传统写法(前端):
const userService = new UserService(new UserRepository(new MongoClient()))
// 你要自己 new 所有依赖,层层嵌套
Spring 写法(后端):
@Autowired
private UserService userService;
// 框架自动创建所有依赖,你直接用就行
前端类比:
// Vue 3 的 provide/inject
// 父组件 provide('userService', new UserService())
// 子组件 const userService = inject('userService')5.4 数据层注解
java
// ===== MongoDB =====
@Document(collection = "user_mst") // 标记这个类映射到 MongoDB 的 user_mst 集合
@Id // 标记主键字段
// ===== MySQL =====
@TableName("daily_statistics") // 标记这个类映射到 MySQL 的 daily_statistics 表
@TableId(type = IdType.AUTO) // 标记主键并设置为自增5.5 常见辅助注解
java
@Slf4j
// 自动生成日志对象 log
// 前端类比:const log = console
// 用法:log.info("用户 {} 登录成功", uid);
// log.error("登录失败", exception);
@Value("${app.name:默认值}")
// 从配置文件读取值
// 前端类比:const appName = import.meta.env.VITE_APP_NAME ?? '默认值'
@PostConstruct
// 对象创建完成后自动执行(只执行一次)
// 前端类比:useEffect(() => { /* 初始化 */ }, [])
// 或 Vue 的 onMounted()
@ConditionalOnProperty(name = "feature.xx", havingValue = "true")
// 根据配置决定是否加载这个类
// 前端类比:if (featureFlags.xx) { loadModule() }5.6 注解速查卡片
| 注解 | 一句话解释 | 前端类比 |
|---|---|---|
@RestController | 这个类是 API 入口 | API route handler |
@RequestMapping | URL 前缀 | app.use('/prefix') |
@GetMapping | 处理 GET 请求 | router.get() |
@PostMapping | 处理 POST 请求 | router.post() |
@RequestBody | 读取请求体 JSON | req.body |
@RequestHeader | 读取请求头 | req.headers['xxx'] |
@PathVariable | 读取路径参数 | req.params.xxx |
@RequestParam | 读取查询参数 | req.query.xxx |
@Validated | 自动校验参数 | zod.parse() |
@Service | 标记业务逻辑类 | Service 模块 |
@Autowired | 自动注入依赖 | inject() / useContext() |
@Slf4j | 自动生成 log | console |
@Value | 读取配置值 | import.meta.env |
@Document | MongoDB 集合映射 | — |
@TableName | MySQL 表映射 | — |
