前几天,阿芬的一个朋友去面试了。面试官问他,你知道SpringMVC的实现过程吗?朋友回答完后,面试官接连问了几个问题,然后面试官说,优哥是训练出来的吧?我的朋友目瞪口呆。我的培训是在一年前进行的。这一切我都知道。所以我找阿芬投诉这件事。阿芬听了之后,觉得果然如此。我没有委屈。SpringMVC的执行过程,大家看这张图,真的没有问题对吧,用户的HTTP请求提交给了DispatcherServlet。DispatcherServlet控制器查询一个或多个HandlerMapping以找到处理请求的Controller。DispatcherServlet将请求提交给Controller。Controller调用业务逻辑处理后,返回给ModelAndView。业务逻辑处理完成后,DispatcherServlet查询ModelAndViewDispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图。这个时候解析ModelAndView,反馈给浏览器。Http响应:视图负责将结果显示给客户端。这时候有面试官会问你,说如果我不想通过视图解析器使用任何注解,那么返回的数据就是Json了,这个大家一定很熟悉,直接回答@ResponseBody就行了。这部分内容很多的培训机构会教学生背诵,而不是教怎么理解。如果不深挖,这个内容就直接pass了,但是很多稍微大一点的“工厂”肯定会继续下去,比如:下面说说SpringMVC的工作机制。这时候,小伙伴们的心里就会出现很大的困惑。机制?原则?机制和原理有什么区别?SpringMVC的工作机制对于大家来说,SpringMVC的执行过程大家一定很熟悉了。这相信每个人的答案都会是完美的。然后再看机制。SpringMVC框架实际上围绕DispatcherServlet工作。这个类也特别重要。其实看到这个名字,阿芬第一时间想到的是它是不是一个替代的Servlet,而我们学过Java的肯定都知道Servlet可以拦截HTTP发送的请求。当我们的Servlet初始化的时候,也就是调用init方法的时候,SpringMVC会根据配置获取配置信息,从而获取到URI和处理器Handler的映射关系,而这个URI就是一个统一的资源标识。.为了更灵活的操作,增强一些我们需要的功能,此时SpringMVC也会在处理器中加入拦截器。SpringMVC容器在初始化的时候,会建立所有url和controller的对应关系。ApplicationObjectSupport里面有很多内容。我简化了源代码部分。Initializewithpassed-incontext.if(!requiredContextClass().isInstance(context)){thrownewApplicationContextException("Invalidapplicationcontext:needstobeoftype["+requiredContextClass().getName()+"]");}this.applicationContext=context;this.messageSourceAccessor=newMessageSourceAccessor(context);initApplicationContext(context);}}这里注意initApplicationContext(context);这个方法在子类中实现:子类AbstractDetectingUrlHandlerMapping实现这个方法:applicationContext.getBeanNamesForType(Object.class));//取任何我们可以确定的bean名称//URL路径发现:我们认为这是一个处理程序。这个时候我们需要保存urls和beanName的对应关系,registerHandler(urls,beanName);}}if((logger.isDebugEnabled()&&!getHandlerMap().isEmpty())||logger.isTraceEnabled()){logger.debug("Detected"+getHandlerMap().size()+"mappingsin"+formatMappingName());}}通过父类的registerHandler放入HandlerMap而当我们使用SpringMVC的Controller中的注解解析Url,我们通过什么课程?什么方法?这是下一个方法。您可以看到注释//determinethegivenurlprocessorbean。(确定给定处理程序bean的URL。)protectedabstractString[]determineUrlsForHandler(StringbeanName);我们在日常生活中写CRUD的时候,在创建Controller的时候,总会用到上面的@RequestMapping注解,里面写的是我们从前端ajax或者其他方法请求的路径,这时候就用这个方法来进行Controller与url的对应关系。这个时候关系就完成了,接下来肯定是根据url找到Controller,继续往下执行。这个时候你写的Controller方法就会被执行。是不是相当于我们Servlet中的doService方法呢?我不会详细解释这一步。可以参考 Servlet的分析呢。最后一步是通过反射调用处理请求的方法。这个时候我们会返回一个视图给大家,也就是我们的返回。但是这个返回对于JSP、JSON、Velocity、FreeMarker、XML、PDF、Excel、Html等字符流也有讲究,那么应该如何处理呢?接下来阿粉就带大家来看看这张图中的UrlBaseViewResolver。班级名字真的很好。先说返回JSP,配置如下:servlet.view.JstlView"/>
