Skip to content

Commit bd56e4c

Browse files
committed
1 parent 0bb13df commit bd56e4c

File tree

5 files changed

+336
-8
lines changed

5 files changed

+336
-8
lines changed
39.9 KB
Loading

note/spring-mvc.md

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1201,4 +1201,53 @@ public String echo(SimpleModel simpleModel, Model model) {
12011201
}
12021202
```
12031203

1204-
经过测试可以发现,SimpleModel参数既可以接收get请求,也可以接收post请求。那么在这种情况下请求参数是被哪个参数解析器解析的呢,debug发现: ServletModelAttributeMethodProcessor
1204+
经过测试可以发现,SimpleModel参数既可以接收get请求,也可以接收post请求。那么在这种情况下请求参数是被哪个参数解析器解析的呢,debug发现: ServletModelAttributeMethodProcessor:
1205+
1206+
![ServletModelAttributeMethodProcessor](images/ServletModelAttributeMethodProcessor.jpg)
1207+
1208+
核心的supportsParameter方法由父类ModelAttributeMethodProcessor实现:
1209+
1210+
```java
1211+
@Override
1212+
public boolean supportsParameter(MethodParameter parameter) {
1213+
return (parameter.hasParameterAnnotation(ModelAttribute.class) ||
1214+
(this.annotationNotRequired && !BeanUtils.isSimpleProperty(parameter.getParameterType())));
1215+
}
1216+
```
1217+
1218+
可以看出,这里支持带有ModelAttribute注解或者是非基本类型的参数解析,同时annotationNotRequired必须设为false,即ModelAttribute注解不必存在,这里是在ServletModelAttributeMethodProcessor的构造器中进行控制的,
1219+
RequestMappingHandlerAdapter.getDefaultArgumentResolvers部分源码:
1220+
1221+
```java
1222+
resolvers.add(new ServletModelAttributeMethodProcessor(false));
1223+
```
1224+
1225+
此类的作用是对@ModelAttribute注解标注的参数进行解析,假设我们将Controller方法改写成:
1226+
1227+
```java
1228+
@RequestMapping("/echoAgain")
1229+
public String echo(@ModelAttribute SimpleModel simpleModel, Model model) {
1230+
model.addAttribute("echo", "hello " + simpleModel.getName() + ", your age is " + simpleModel.getAge() + ".");
1231+
System.out.println(model.asMap().get("simpleModel"));
1232+
return "echo";
1233+
}
1234+
```
1235+
1236+
首先,Spring会首先反射生成一个SimpleModel对象,之后将从request中获取的参数尝试设置到SimpleModel对象中去,最后将此对象放置到Model中(本质上就是一个Map),key就是simpleModel.下面我们来看一下具体的解析过程,整个过程可以分为
1237+
以下三部分:
1238+
1239+
### 参数对象构造
1240+
1241+
因为SimpleModel是一个对象类型,所以要想将参数注入到其中,第一步必然是先创建一个对象,创建的入口位于ModelAttributeMethodProcessor的resolveArgument方法,相关源码:
1242+
1243+
```java
1244+
//name在这里便是simpleModel
1245+
String name = ModelFactory.getNameForParameter(parameter);
1246+
Object attribute = (mavContainer.containsAttribute(name) ? mavContainer.getModel().get(name) :
1247+
createAttribute(name, parameter, binderFactory, webRequest));//反射实例化
1248+
```
1249+
1250+
ModelAndViewContainer是个什么东西呢,从名字就可以看出就,它是Spring MVC里两个重要概念Model和View的组合体,用来记录在请求响应过程中Model和View的变化,在这里可以简单理解为去Model中检查有没有叫simpleModel的属性已经存在。
1251+
1252+
### 参数绑定
1253+

0 commit comments

Comments
 (0)