DispatcherServlet
DispatcherServlet是由Spring创建,初始化是由Tomcat;
# 初始化时机
默认第一次调用初始化;
@Configuration
@ComponentScan
@PropertySource("classpath:application.properties")
@EnableConfigurationProperties({WebMvcProperties.class, ServerProperties.class})//绑定配置类中键值spring.mvc.servlet
public class WebConfig {
// 内嵌web容器工厂
@Bean
public TomcatServletWebServerFactory tomcatServletWebServerFactory(ServerProperties serverProperties) {
return new TomcatServletWebServerFactory(serverProperties.getPort());
}
// 创建DispatcherServlet
@Bean
public DispatcherServlet dispatcherServlet(){
return new DispatcherServlet();
}
// 注册DispatcherServlet,SpringMVC的入口
@Bean
public DispatcherServletRegistrationBean dispatcherServletRegistrationBean(DispatcherServlet dispatcherServlet,
WebMvcProperties webMvcProperties){
DispatcherServletRegistrationBean registrationBean = new DispatcherServletRegistrationBean(dispatcherServlet, "/");
// registrationBean.setLoadOnStartup(1);//>0就在tomcat启动时就初始化,否则第一次调用初始化
registrationBean.setLoadOnStartup(webMvcProperties.getServlet().getLoadOnStartup());
return registrationBean;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 初始化执行操作
调用DispatcherServlet类中的onRefresh方法;
protected void onRefresh(ApplicationContext context) {
this.initStrategies(context);
}
protected void initStrategies(ApplicationContext context) {
this.initMultipartResolver(context);// 初始化文件上传解析器
this.initLocaleResolver(context);
this.initThemeResolver(context);
this.initHandlerMappings(context);// 路径映射
this.initHandlerAdapters(context);// 请求处理 适配器
this.initHandlerExceptionResolvers(context);// 解析异常
this.initRequestToViewNameTranslator(context);
this.initViewResolvers(context);
this.initFlashMapManager(context);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 处理器映射器
RequestMappingHandlerMapping
负责找到请求 对应的控制器方法;
不使用DispatcherServlet初始化时默认添加的组件,只会将RequestMappingHandlerMapping作为DispatcherServlet的成员变量,不会作为Bean;
DispatcherServlet.properties:
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\ org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping,\ org.springframework.web.servlet.function.support.RouterFunctionMapping org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\ org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\ org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter,\ org.springframework.web.servlet.function.support.HandlerFunctionAdapter
1
2
3
4
5
6
7
8
webConfig中:
// 如果用 DispatcherServlet 初始化时默认添加的组件, 并不会作为 bean
@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping(){
return new RequestMappingHandlerMapping();
}
1
2
3
4
5
2
3
4
5
添加Controller:
@Controller
public class Controller1 {
private static final Logger log = LoggerFactory.getLogger(Controller1.class);
@GetMapping("/test1")
public ModelAndView test1() throws Exception {
log.debug("test1()");
return null;
}
@PostMapping("/test2")
public ModelAndView test2(@RequestParam("name") String name) {
log.debug("test2({})", name);
return null;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
测试:
public class Dispatcher_test {
private static final Logger log = LoggerFactory.getLogger(Dispatcher_test.class);
public static void main(String[] args) throws Exception {
AnnotationConfigServletWebServerApplicationContext context =
new AnnotationConfigServletWebServerApplicationContext(WebConfig.class);
// 作用 解析 @RequestMapping 以及派生注解,生成路径与控制器方法的映射关系,在初始化时就生成
RequestMappingHandlerMapping handlerMapping = context.getBean(RequestMappingHandlerMapping.class);
// 获取映射结果
Map<RequestMappingInfo, HandlerMethod> handlerMethods = handlerMapping.getHandlerMethods();
handlerMethods.forEach((k, v) -> {
System.out.println(k + "=" + v);
});
// 请求过来,获取控制器方法,返回处理器执行链对象
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/test1");
MockHttpServletResponse response = new MockHttpServletResponse();
HandlerExecutionChain chain = handlerMapping.getHandler(request);
System.out.println(chain);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{GET [/test1]}=com.Nreal.MVC.dispatcher.Controller1#test1() {POST [/test2]}=com.Nreal.MVC.dispatcher.Controller1#test2(String) HandlerExecutionChain with [com.Nreal.MVC.dispatcher.Controller1#test1()] and 0 interceptors
1
2
3
# 处理器适配器
调用控制器方法;
RequestMappingHandlerAdapter中invokeHandlerMethod为protected,其它类想要调用可以创建其子类修改访问修饰符;
public class MyRequestMappingHandlerAdapter extends RequestMappingHandlerAdapter {
@Override
public ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
return super.invokeHandlerMethod(request, response, handlerMethod);
}
}
1
2
3
4
5
6
2
3
4
5
6
webConfig中:
@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
return new MyRequestMappingHandlerAdapter();
}
1
2
3
4
2
3
4
测试代码全部:
public class Dispatcher_test {
private static final Logger log = LoggerFactory.getLogger(Dispatcher_test.class);
public static void main(String[] args) throws Exception {
AnnotationConfigServletWebServerApplicationContext context =
new AnnotationConfigServletWebServerApplicationContext(WebConfig.class);
// 作用 解析 @RequestMapping 以及派生注解,生成路径与控制器方法的映射关系,在初始化时就生成
RequestMappingHandlerMapping handlerMapping = context.getBean(RequestMappingHandlerMapping.class);
// 获取映射结果
Map<RequestMappingInfo, HandlerMethod> handlerMethods = handlerMapping.getHandlerMethods();
handlerMethods.forEach((k, v) -> {
System.out.println(k + "=" + v);
});
// 请求过来,获取控制器方法,返回处理器执行链对象
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/test1");
MockHttpServletResponse response = new MockHttpServletResponse();
HandlerExecutionChain chain = handlerMapping.getHandler(request);
System.out.println(chain);
System.out.println(">>>>>>>>>>>>>>>>>>>>>");
// HandlerAdapter作用:调用控制器方法
MyRequestMappingHandlerAdapter handlerAdapter = context.getBean(MyRequestMappingHandlerAdapter.class);
handlerAdapter.invokeHandlerMethod(request, response, (HandlerMethod) chain.getHandler());
System.out.println(">>>>>>>>>>>>>>>>>>>>> 所有参数解析器");
for (HandlerMethodArgumentResolver resolver : handlerAdapter.getArgumentResolvers()) {
System.out.println(resolver);
}
System.out.println(">>>>>>>>>>>>>>>>>>>>> 所有返回值解析器");
for (HandlerMethodReturnValueHandler handler : handlerAdapter.getReturnValueHandlers()) {
System.out.println(handler);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37