@RequestParam 用于获取 URL 中的查询参数(Query String)或表单参数,适合 GET 请求。
java复制代码
package com.example.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ParamController {
@GetMapping("/greet")
public String greet(@RequestParam String name,
@RequestParam(defaultValue = "18") int age) {
return "Hello, " + name + "! Your age is " + age;
}
}
访问 http://localhost:8080/greet?name=Tom&age=20,返回 Hello, Tom! Your age is 20。其中 defaultValue 表示参数缺省时的默认值。
4.4.2 使用 @PathVariable 获取路径参数
@PathVariable 用于获取 URL 路径中的参数,适合 RESTful 风格的接口。
java复制代码
package com.example.demo.controller;
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("/user/{id}")
public String getUser(@PathVariable Long id) {
return "User id: " + id;
}
}
访问 http://localhost:8080/user/1001,返回 User id: 1001。
4.4.3 使用 @RequestBody 接收 JSON 请求体
@RequestBody 用于将请求体中的 JSON 数据反序列化为 Java 对象,适合 POST 请求。
java复制代码
package com.example.demo.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@PostMapping("/user")
public String createUser(@RequestBody User user) {
return "Created user: " + user.getName();
}
}
对应的实体类:
java复制代码
package com.example.demo.entity;
public class User {
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.example.demo.entity;
import lombok.Data;
@Data
public class User {
private Long id;
private String name;
private Integer age;
}
12.3 Mapper 层(数据访问层)
这里用 @Repository 标记,并模拟从内存中查询数据:
java复制代码
package com.example.demo.mapper;
import com.example.demo.entity.User;
import org.springframework.stereotype.Repository;
@Repository
public class UserMapper {
public User findById(Long id) {
// 模拟数据库查询
User user = new User();
user.setId(id);
user.setName("Tom");
user.setAge(20);
return user;
}
}
12.4 Service 层(业务层)
先定义接口,再提供实现类:
java复制代码
package com.example.demo.service;
import com.example.demo.entity.User;
public interface UserService {
User getUserById(Long id);
}
java复制代码
package com.example.demo.service.impl;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public User getUserById(Long id) {
return userMapper.findById(id);
}
}
12.5 Controller 层(控制层)
使用 @PathVariable 接收路径参数,调用 Service 层返回结果:
java复制代码
package com.example.demo.controller;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
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 {
@Autowired
private UserService userService;
@GetMapping("/user/{id}")
public User getUser(@PathVariable Long id) {
return userService.getUserById(id);
}
}
依赖注入(Dependency Injection,简称 DI)是 Spring 框架的核心机制之一。它让对象之间的依赖关系由容器在运行时自动装配,而不是在代码中手动 new 出来,从而降低耦合、提升可测试性和可维护性。
13.1 什么是依赖注入
简单来说,依赖注入就是「把对象需要的依赖,由外部容器注入进来,而不是自己创建」。例如 UserServiceImpl 需要用到 UserMapper,它并不自己 new UserMapper(),而是通过注解让 Spring 容器把 UserMapper 的实例注入进来。
java复制代码
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper; // 由 Spring 容器注入,而非手动 new
@Override
public User getUserById(Long id) {
return userMapper.findById(id);
}
}
13.2 依赖注入的三种方式
Spring 支持三种常见的依赖注入方式,各有适用场景。
13.2.1 字段注入(Field Injection)
直接在字段上使用 @Autowired,写法最简洁,也是初学者最常用的方式:
java复制代码
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
}
@Service
public class UserServiceImpl implements UserService {
private final UserMapper userMapper;
@Autowired
public UserServiceImpl(UserMapper userMapper) {
this.userMapper = userMapper;
}
@Override
public User getUserById(Long id) {
return userMapper.findById(id);
}
}
@Configuration
public class DataSourceConfig {
@Bean
@Primary
public DataSource primaryDataSource() {
return new HikariDataSource();
}
@Bean
public DataSource backupDataSource() {
return new HikariDataSource();
}
}
当同类型存在多个 Bean 时,也可以使用 @Qualifier 指定要注入的 Bean 名称:
java复制代码
@Service
public class UserServiceImpl implements UserService {
@Autowired
@Qualifier("backupDataSource")
private DataSource dataSource;
}
13.4 依赖注入与分层架构的结合
结合前面介绍的分层规范,依赖注入贯穿了 Controller → Service → Mapper 的整个调用链:
text复制代码
Controller 层 --注入--> Service 层 --注入--> Mapper/Repository 层
每一层都通过接口或类声明依赖,由 Spring 容器统一装配,各层之间无需关心对方如何创建,真正做到「面向接口编程、依赖倒置」。
13.5 小结
依赖注入是 Spring 的核心能力,它让对象之间的协作关系由容器统一管理。掌握字段注入、构造器注入和 Setter 注入的区别,理解按类型、按名称、@Primary、@Qualifier 的匹配规则,是深入使用 Spring Boot 的必备基础。工程化项目中推荐优先使用构造器注入,让依赖关系更清晰、更易测试。