DispacherServlet作为一个入口,请求来了之后,都是到DispacherServlet中,会走它的doService方法,在doService方法中,调用doDispatch方法。然后分发请求
doDispatch方法如下(简化之后)
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { try { ModelAndView mv = null; try { // 根据request来获取相对应的handler(也就是controller) mappedHandler = getHandler(processedRequest); // 根据request来获取相对应要调用的controller中的具体方法(可以这么理解) HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // 具体调用controller中的方法,返回视图 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // 这些都是视图相关的了吧 applyDefaultViewName(processedRequest, mv); mappedHandler.applyPostHandle(processedRequest, response, mv); } }
根据源代码知道,springmvc做了两件事,才找到要执行的方法。
1、找handler(即controller)
2、找adapter(即controller中方法)
流程如下
从流程可以知道,Springmvc的两个很重要的接口 HandlerMapping 和 HandlerAdapter
request通过 HandlerMapping 找到 HandlerExecutionChain(handler+拦截器)
然后再通过 HandlerAdapter 找到 对应的处理映射,来执行 handler中具体的方法。
HandlerMapping 和 HandlerAdapter 是两个顶级接口,它们分别都有几个实现
HandlerMapping 的具体实现
1、BeanNameUrlHandlerMapping (Springmvc默认):作用是找handler,根据springmvc的配置文件中配置的<bean name="/url" class="Controller"></bean> 来找到对应的Controller。这样url和Controller就一一对应了,一个controller的bean对应一个url
2、SimpleUrlHandlerMapping 推荐使用:作用是找handler,在springmvc的配置文件中配置,配置如下
<bean id="test1" class="com.pptv.controller.Test1Controller"></bean> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/hello.do">test1</prop> </props> </property> </bean>
这个就把controller 的 bean 和 url 分开来了,更加方便维护。
3、ControllerClassNameHandlerMapping 不推荐:作用是找handler,在springmvc的配置文件中配置,访问时,通过controller类名可以访问,类名首字母小写。如配置为
<bean class="com.pptv.controller.TestController"></bean>
那么访问时,url可以为 /test、/test111、 /testController ...都可以访问到(待验证)。
4、RequestMappingHandlerMapping 这个是注解开发相关的。在Controller类加上@Controller就可以找到对应的了。
HandlerAdaper的具体实现
1、SimpleControllerHandlerAdapter:需要controller实现接口Controller,并实现方法
handleRequest,这个方法返回一个视图。
2、HttpRequestHandlerAdapter:需要controller实现接口HttpRequestHandler,并实现方法
handlerRequest,这个方法返回void。
3、RequestMappingHandlerAdapter 这个是注解开发相关的,和RequestMappingHandlerMapping配对使用。
HandlerMapping 和 HandlerAdaper 分别 还有个具体实现,叫 Annotation...的,名字记不清楚,不过这个是3.0版本以前用的,也是注解相关,现在分别用RequestMappingHandlerMapping 和 RequestMappingHandlerAdaper 代替。
要想使用 RequestMappingHandlerMapping 和 RequestMappingHandlerAdaper 。在springmvc的配置文件中必须添加
<context:component-scan base-package="com.pptv.controller"/> <mvc:annotation-driven/>
这两个配置,第一个是告诉spring,要注册@Controller、@Component, @Service, @Repository等等这些类
第二个配置,是告诉springmvc,要用注解驱动。这个配置其实就是注册了一些类,最重要的两个就是
RequestMappingHandlerMapping 和 RequestMappingHandlerAdaper (3.0版本之后,之前是Annotation...)