35、请求处理-【源码分析】-自定义参数绑定原理
35、请求处理-【源码分析】-自定义参数绑定原理
自定义参数绑定原理主要涉及Spring Boot如何将HTTP请求中的参数自动绑定到控制器方法的自定义对象参数上。以下是详细的解析:
### 1. 参数解析器的选择
- **HandlerMethodArgumentResolverComposite**:
- Spring Boot内部维护了一个`HandlerMethodArgumentResolverComposite`,它包含多个`HandlerMethodArgumentResolver`实例。
- 当处理请求时,会遍历这些解析器,调用`supportsParameter`方法判断哪个解析器支持当前参数类型。
### 2. ServletModelAttributeMethodProcessor
- **支持参数类型**:
- `ServletModelAttributeMethodProcessor`是关键的参数解析器,负责处理自定义POJO类型的参数。
- 它通过`supportsParameter`方法判断参数是否满足以下条件:
- 参数类型不是简单类型(如基本类型、集合等)。
- 参数上存在`@ModelAttribute`注解,或没有该注解但`annotationNotRequired`为`true`。
### 3. 参数绑定过程
#### 创建目标对象
- **创建空对象**:
- 调用`createAttribute`方法,通过反射创建自定义POJO类型的空对象实例。
#### 数据绑定
- **WebDataBinder**:
- 使用`WebDataBinderFactory`创建`WebDataBinder`实例,用于将请求参数绑定到目标对象。
- `WebDataBinder`内部维护了`Converters`集合,用于数据类型转换。
- **绑定请求参数**:
- 调用`bindRequestParameters`方法,遍历请求中的所有参数。
- 通过反射获取目标对象的属性,将请求参数值设置到对应的属性上。
- 利用`Converters`进行类型转换,例如将字符串转换为日期类型。
### 4. 示例说明
假设有以下控制器方法:
```java
@PostMapping("/saveUser")
public String saveUser(Person person) {
// ...
}
```
其中,`Person`类包含`name`、`age`和`birth`属性。
当提交表单数据:
```
name=张三&age=18&birth=2020-01-01
```
- **参数解析**:
- `ServletModelAttributeMethodProcessor`识别`Person`类型参数。
- 创建`Person`对象实例。
- 使用`WebDataBinder`将请求参数绑定到`Person`对象的属性上。
### 5. 自定义类型转换
- **Converter注册**:
- 若需要自定义类型转换,例如将特定格式的字符串转换为自定义类型,可以实现`Converter`接口。
- 通过`WebMvcConfigurer`的`addFormatters`方法将自定义`Converter`注册到`FormattingConversionService`中。
### 6. 总结
自定义参数绑定原理:
1. **解析器选择**:通过`HandlerMethodArgumentResolverComposite`找到支持自定义POJO类型的`ServletModelAttributeMethodProcessor`。
2. **对象创建**:创建目标POJO对象实例。
3. **数据绑定**:利用`WebDataBinder`将请求参数绑定到对象属性,借助`Converters`进行类型转换。
通过理解这一原理,可以更灵活地处理各种复杂的请求参数绑定需求。