本文共 4048 字,大约阅读时间需要 13 分钟。
DispatcherServlet是springMvc处理请求的核心逻辑,简单描述一下处理流程,
首先需要在web.xml中配置该Servlet的服务路径,默认是/*所有路径,这样web请求就从Servlet 容器把控制权流转到DispatcherServlet,看一下DispatcherServlet的核心方法:protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception { //...省略部分代码,看到这里把请求委托给doDispatch try { doDispatch(request, response); } //...省略部分代码}
继续看一下doDispatch:
//省略部分代码,根据用户的请求,查找对应得handlermappedHandler = getHandler(processedRequest);//根据handler查找对应得适配器HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
再来看一下:
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { //遍历handlerMappings查找符合的类 if (this.handlerMappings != null) { for (HandlerMapping mapping : this.handlerMappings) { HandlerExecutionChain handler = mapping.getHandler(request); if (handler != null) { return handler; } } } return null;}
再看一下handler适配器种类:
HandlerAdapter (org.springframework.web.servlet) HttpRequestHandlerAdapter (org.springframework.web.servlet.mvc) SimpleServletHandlerAdapter (org.springframework.web.servlet.handler) AbstractHandlerMethodAdapter (org.springframework.web.servlet.mvc.method) RequestMappingHandlerAdapter (org.springframework.web.servlet.mvc.method.annotation) SimpleControllerHandlerAdapter (org.springframework.web.servlet.mvc)
适配HttpRequestHandler,Servlet,Controller,@RequestMapping
接下来看一下如何把HandlerMapping和HandlerAdapter配置到spring中:
private void initHandlerMappings(ApplicationContext context) { this.handlerMappings = null; if (this.detectAllHandlerMappings) { //查找子父容器中所有类型是HandlerMapping的类 MapmatchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false); if (!matchingBeans.isEmpty()) { this.handlerMappings = new ArrayList<>(matchingBeans.values()); // We keep HandlerMappings in sorted order. AnnotationAwareOrderComparator.sort(this.handlerMappings); } } else { try { HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class); //保存到字段中 this.handlerMappings = Collections.singletonList(hm); } catch (NoSuchBeanDefinitionException ex) { // Ignore, we'll add a default HandlerMapping later. } } //省略部分代码}
初始化HandlerAdapter和上面类似:
private void initHandlerAdapters(ApplicationContext context) { this.handlerAdapters = null; if (this.detectAllHandlerAdapters) { // Find all HandlerAdapters in the ApplicationContext, including ancestor contexts. MapmatchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false); if (!matchingBeans.isEmpty()) { this.handlerAdapters = new ArrayList<>(matchingBeans.values()); // We keep HandlerAdapters in sorted order. AnnotationAwareOrderComparator.sort(this.handlerAdapters); } } else { try { HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class); this.handlerAdapters = Collections.singletonList(ha); } catch (NoSuchBeanDefinitionException ex) { // Ignore, we'll add a default HandlerAdapter later. } } //省略部分代码}
来实践一下:
自定义一个类:public class MyController implements HttpRequestHandler { @Override public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setHeader(HttpHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN_VALUE); ServletOutputStream os = response.getOutputStream(); BufferedOutputStream bos = new BufferedOutputStream(os); bos.write("my controller...".getBytes()); bos.flush(); }}
适配器配置:
@Configurationpublic class MyMappingConfig { @Bean public HandlerMapping handlerMapping(){ SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping(); Mapmap = new HashMap<>(); map.put("/test/test.html", new MyController()); mapping.setUrlMap(map); mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 100); return mapping; }}
结果展示:
my controller...
可以通过这种方式在jar包中,配合自动注入,把自己的服务暴露出去.
比如:spring的actuator(当然,其应用比这里复杂很多)转载地址:http://dduti.baihongyu.com/