文章目录
P156 DispatcherServlet 源码分析
找doGet 和doPost方法(继承Httpservlet后重要的两个方法): 发现里面调用了processRequest()方法
发现在 processRequest() 重点是调用了doService() 方法
doService() 是本类也就是FrameworkServlet中的抽象方法 所以需要找实现了doService()方法(在DispatcherServlet中)
在DispatcherServlet 中找到了doService的实现方法
最重要的地方:
try中的内容比较重要!
重点: doDispathch方法 (该方法在本类DispatcherServlet中定义)
总结:
重点:研究doDispatch()该方法
P157 基本的请求流程
doDispatch() 两个关键的位置:
1.目标方法执行:
2.页面跳转
3.大体流程:
重点看第二步
getHandler() 方法(第二步)
返回值中的handler封装了处理对应请求的处理器类(Controller)。
getHandlerAdapter()(第四步)
拿到处理器类对应的适配器来执行目标方法(看作是一个反射工具)
返回值为处理注解方法的适配器 ha
ha.handle() (第五步)
适配器执行目标方法 返回值为modelAndView (数据和视图)
processDispatchResult() (第六步)
P158 HandlerMapping
doDispatch()总结:
细节1: getHandler()
getHandler(processRequest) processRequest 保存了当前请求的地址/hello
重点:对getHandler()研究 增强for循环:
handlerMappings(处理器映射)保存了:每一个处理器能处理哪些请求的 映射信息(每个处理器都加了@Controller的注解,在Spring容器启动时,就创建了对应的对象,扫描注解的过程中将对应的方法和类保存在handlerMap)
在handlerMappings中寻找对应的处理器。
重点:对getHandlerAdaptor()研究
AnnotationMethodHandlerAdaptor:能解析注解方式的适配器
增强for循环,判断是否支持(是否实现了HttpRequestHandler接口)
重载的supports方法
P161 九大组件
总结:
==探究一下for each() 中 HandlerMappings 和 HandlerAdapters 什么时候有值 ==
HandlerMappings 和 HandlerAdapters 作为DispatcherServlet的属性
九大组件(DispatcherServlet的属性)
九大组件全部都是接口,接口就是规范,提供了非常强大的扩展性
DispatcherServlet 中的 onRefresh 方法
在服务器一启动的时候就进行初始化
initHandlerMappings() 该初始化方法:
探查所有handlerMapping
可以手动地修改(web.xml中):
P163 执行目标方法
拿到适配器进行执行目标方法(反射)的时候,参数的传入是多种多样的,这是一个需要研究的问题!
最终的执行目标方法的地方:传入目标处理器方法、处理器类、包装后的原生request、response、隐含模型(BindingAwareModelMap )
找到@ModelAttribute注解标注的方法
resolveHandlerAArguments()解析ModelAttribute方法的参数;
变成可访问的模式,然后进行反射执行
resolveHandlerArguments() 方法(获取参数)
针对ModelAttribute方法
找注解的过程中,如果某个参数的注解大于一个则抛出异常,因此某个参数中的注解只能有一个。我们这里参数中没有注解,只有Map
参数注解大于1个,抛出异常
没有找到注解的情况下:
返回类型的小写作为attrName
隐含模型中的内容,就是ModelAtrribute标注的方法中添加进去的
将返回值放到隐含模型中
执行完ModelAttribute方法后,接下来就执行目标方法。
可以看到:ModelAttribute标注的方法先于目标方法执行,并将自己的返回值放到隐含模型中。
执行目标方法之前,先要获取目标方法的参数。
接下来关注:解析目标方法的参数参数 “resolveHandlerArguments()方法”
目标方法的参数:
private Object[] resolveHandlerArguments(Method handlerMethod, Object handler,
NativeWebRequest webRequest, ExtendedModelMap implicitModel) throws Exception {
// 获取ModelAttribute方法的参数类型
Class[] paramTypes = handlerMethod.getParameterTypes();
// 初始化一个长度大小为参数数组长的返回值
Object[] args = new Object[paramTypes.length];
for (int i = 0; i < args.length; i++) {
MethodParameter methodParam = new MethodParameter(handlerMethod, i);
methodParam.initParameterNameDiscovery(this.parameterNameDiscoverer);
GenericTypeResolver.resolveParameterType(methodParam, handler.getClass());
String paramName = null;
String headerName = null;
boolean requestBodyFound = false;
String cookieName = null;
String pathVarName = null;
String attrName = null;
boolean required = false;
String defaultValue = null;
boolean validate = false;
Object[] validationHints = null;
int annotationsFound = 0;
// 获得参数上的注解
Annotation[] paramAnns = methodParam.getParameterAnnotations();
// 【判断是什么类型的注解】
for (Annotation paramAnn : paramAnns) {
// 判断是否RequestParam注解
if (RequestParam.class.isInstance(paramAnn)) {
// 类型转换
RequestParam requestParam = (RequestParam) paramAnn;
// 注解的value赋值给 paramName
paramName = requestParam.value();
required = requestParam.required();
defaultValue = parseDefaultValueAttribute(requestParam.defaultValue());
annotationsFound++;
}
else if (RequestHeader.class.isInstance(paramAnn)) {
RequestHeader requestHeader = (RequestHeader) paramAnn;
headerName = requestHeader.value();
required = requestHeader.required();
defaultValue = parseDefaultValueAttribute(requestHeader.defaultValue());
annotationsFound++;
}
else if (RequestBody.class.isInstance(paramAnn)) {
requestBodyFound = true;
annotationsFound++;
}
else if (CookieValue.class.isInstance(paramAnn)) {
CookieValue cookieValue = (CookieValue) paramAnn;
cookieName = cookieValue.value();
required = cookieValue.required();
defaultValue = parseDefaultValueAttribute(cookieValue.defaultValue());
annotationsFound++;
}
else if (PathVariable.class.isInstance(paramAnn)) {
PathVariable pathVar = (PathVariable) paramAnn;
pathVarName = pathVar.value();
annotationsFound++;
}
else if (ModelAttribute.class.isInstance(paramAnn)) {
ModelAttribute attr = (ModelAttribute) paramAnn;
attrName = attr.value();
annotationsFound++;
}
else if (Value.class.isInstance(paramAnn)) {
defaultValue = ((Value) paramAnn).value();
}
else if (paramAnn.annotationType().getSimpleName().startsWith("Valid")) {
validate = true;
Object value = AnnotationUtils.getValue(paramAnn);
validationHints = (value instanceof Object[] ? (Object[]) value : new Object[] {value});
}
}
// 【某个参数的注解个数大于1,抛出异常】
if (annotationsFound > 1) {
throw new IllegalStateException("Handler parameter annotations are exclusive choices - " +
"do not specify more than one such annotation on the same parameter: " + handlerMethod);
}
// 【没有注解的参数】
if (annotationsFound == 0) {
// 解析普通参数 【原生API】
Object argValue = resolveCommonArgument(methodParam, webRequest);
if (argValue != WebArgumentResolver.UNRESOLVED) {
args[i] = argValue;
}
else if (defaultValue != null) {
args[i] = resolveDefaultValue(defaultValue);
}
else {
// 获得参数类型
Class<?> paramType = methodParam.getParameterType();
// 判断是Mode类型或者Map类型
if (Model.class.isAssignableFrom(paramType) || Map.class.isAssignableFrom(paramType)) {
if (!paramType.isAssignableFrom(implicitModel.getClass())) {
throw new IllegalStateException("Argument [" + paramType.getSimpleName() + "] is of type " +
"Model or Map but is not assignable from the actual model. You may need to switch " +
"newer MVC infrastructure classes to use this argument.");
}
// 传入隐含模型【之前的ModelAtrribute使用后传入的隐含模型】
args[i] = implicitModel;
}
else if (SessionStatus.class.isAssignableFrom(paramType)) {
args[i] = this.sessionStatus;
}
else if (HttpEntity.class.isAssignableFrom(paramType)) {
args[i] = resolveHttpEntityRequest(methodParam, webRequest);
}
else if (Errors.class.isAssignableFrom(paramType)) {
throw new IllegalStateException("Errors/BindingResult argument declared " +
"without preceding model attribute. Check your handler method signature!");
}
// 【是否是简单类型】基本类型:Integer、String
else if (BeanUtils.isSimpleProperty(paramType)) {
paramName = "";
}
else {
attrName = "";
}
}
}
// 【标了注解,确定注解的值的环节】
// paramName中保存的是注解中的value的值
if (paramName != null) {
args[i] = resolveRequestParam(paramName, required, defaultValue, methodParam, webRequest, handler);
}
else if (headerName != null) {
args[i] = resolveRequestHeader(headerName, required, defaultValue, methodParam, webRequest, handler);
}
else if (requestBodyFound) {
args[i] = resolveRequestBody(methodParam, webRequest, handler);
}
else if (cookieName != null) {
args[i] = resolveCookieValue(cookieName, required, defaultValue, methodParam, webRequest, handler);
}
else if (pathVarName != null) {
args[i] = resolvePathVariable(pathVarName, methodParam, webRequest, handler);
}
// 确定自定义类型参数的值,还要将请求中的每一个参数赋值给这个对象
else if (attrName != null) {
WebDataBinder binder =
resolveModelAttribute(attrName, methodParam, implicitModel, webRequest, handler);
boolean assignBindingResult = (args.length > i + 1 && Errors.class.isAssignableFrom(paramTypes[i + 1]));
if (binder.getTarget() != null) {
doBind(binder, webRequest, validate, validationHints, !assignBindingResult);
}
args[i] = binder.getTarget();
if (assignBindingResult) {
args[i + 1] = binder.getBindingResult();
i++;
}
implicitModel.putAll(binder.getBindingResult().getModel());
}
}
// 返回 ModelAttribute方法中确定的参数
return args;
}
P166 确定POJO中的值
对于自定义类型的值:
三步判断确定pojo中的值
第三步中,如果都没有的话就利用反射创建一个POJO对象,那么其中的部分参数是null。