DispatcherServlet是springMvc处理请求的核心逻辑,简单描述一下处理流程,
首先需要在web.xml中配置该Servlet的服务路径,默认是/*所有路径,这样web请求就从Servlet
容器把控制权流转到DispatcherServlet,看一下DispatcherServlet的核心方法:
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
//...省略部分代码,看到这里把请求委托给doDispatch
try {
doDispatch(request, response);
}
//...省略部分代码
}
继续看一下doDispatch:
//省略部分代码,根据用户的请求,查找对应得handler
mappedHandler = 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的类
Map matchingBeans =
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.
Map matchingBeans =
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();
}
}
适配器配置:
@Configuration
public class MyMappingConfig {
@Bean
public HandlerMapping handlerMapping(){
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
Map map = 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(当然,其应用比这里复杂很多)