Spring MVC原理学习笔记
学习来源:黑马程序员
学习时间:2023年11月4日
1 DispatcherServlet
1.1 初始化时机
代码准备
参见:[[Spring原理#2.2.4 AnnotationConfigServletWebServerApplicationContext]]
1 2 3 4 5 6 7
| @Slf4j public class A20 { public static void main(String[] args) { AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext(WebConfig.class); } }
|
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
| @Configuration @ComponentScan public class WebConfig {
@Bean public TomcatServletWebServerFactory tomcatServletWebServerFactory() { return new TomcatServletWebServerFactory(9090); }
@Bean public DispatcherServlet dispatcherServlet() { return new DispatcherServlet(); }
@Bean public DispatcherServletRegistrationBean dispatcherServletRegistrationBean(DispatcherServlet dispatcherServlet) { return new DispatcherServletRegistrationBean(dispatcherServlet, "/"); } }
|
默认情况下,DispatcherServlet
在接收到第一次请求时进行初始化操作,实际上是调用到了下面的onRefresh
方法:
1 2 3 4
| protected void onRefresh(ApplicationContext context) { this.initStrategies(context); }
|
访问时,打印日志:
可以设置为当Tomcat启动时就初始化DispatcherServlet
:
1 2 3 4 5 6 7 8 9
| @Bean public DispatcherServletRegistrationBean dispatcherServletRegistrationBean(DispatcherServlet dispatcherServlet) { DispatcherServletRegistrationBean registrationBean = new DispatcherServletRegistrationBean(dispatcherServlet, "/"); registrationBean.setLoadOnStartup(1); return registrationBean; }
|
打印结果:
1.2 初始化方法
初始化方法:
1 2 3 4
| protected void onRefresh(ApplicationContext context) { this.initStrategies(context); }
|
onRefresh
又调用了initStrategies
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 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); }
|
注意:初始化时,这些默认添加组件不会作为bean,不会出现在容器里。
1.3 RequestMappingHandlerMapping
- RequestMappingHandlerMapping,中文翻译为处理器映射器。
- 作用:解析
@RequestMapping
注解及其派生注解(例如@GetMapping
,@PostMapping
),生成路径与控制器方法的映射关系
- 映射关系的生成时机:
DispatcherServlet
初始化时,即执行onRefresh
方法时。
- 映射关系由一个Map存储,键为请求方法,值为请求路径
代码演示
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
| @Slf4j @Controller public class Controller1 { @GetMapping("/test1") public ModelAndView test1() { log.debug("test1()"); return null; }
@PostMapping("/test2") public ModelAndView test2(@RequestParam("name") String name) { log.debug("test2({})", name); return null; }
@PutMapping("/test3") public ModelAndView test3(@Token String token) { log.debug("test3({})", token); return null; }
@RequestMapping("/test4.yml") @Yml public User1 test4() { log.debug("test4()"); return new User1("Hongyi", 23); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @Slf4j public class A20 { public static void main(String[] args) throws Exception { AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext(WebConfig.class); RequestMappingHandlerMapping handlerMapping = context.getBean(RequestMappingHandlerMapping.class); Map<RequestMappingInfo, HandlerMethod> handlerMethods = handlerMapping.getHandlerMethods(); handlerMethods.forEach((k, v) -> { System.out.println(k + "=" + v); });
HandlerExecutionChain chain = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/test1")); System.out.println(chain); } }
|
打印结果:
1.4
著作権表示: 此文章版权归Kisugi Takumi所有,如有转载,请注明来自原作者