SpringMVC的作用毋庸置疑,虽然我们现在都是用SpringBoot,但是SpringBoot中仍然是在使用SpringMVC来处理请求。
我们在使用SpringMVC时,传统的方式是通过定义web.xml,比如:
<web-app>
<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
</web-app>
我们只要定义这样的一个web.xml,然后启动Tomcat,那么我们就能正常使用SpringMVC了。
SpringMVC中,最为核心的就是DispatcherServlet,在启动Tomcat的过程中:
- Tomcat会先创建DispatcherServlet对象
- 然后调用DispatcherServlet对象的init()
而在init()方法中,会创建一个Spring容器,并且添加一个ContextRefreshListener监听器,该监听器会监听ContextRefreshedEvent事件(Spring容器启动完成后就会发布这个事件),也就是说Spring容器启动完成后,就会执行ContextRefreshListener中的onApplicationEvent()方法,从而最终会执行DispatcherServlet中的initStrategies(),这个方法中会初始化更多内容:
protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}
其中最为核心的就是HandlerMapping和HandlerAdapter。
什么是Handler?
Handler表示请求处理器,在SpringMVC中有四种Handler:
- 实现了Controller接口的Bean对象
- 实现了HttpRequestHandler接口的Bean对象
- 添加了@RequestMapping注解的方法
- 一个HandlerFunction对象
比如实现了Controller接口的Bean对象:
@Component("/test")
public class JiajiaBeanNameController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("jiajia");
return new ModelAndView();
}
}
实现了HttpRequestHandler接口的Bean对象:
@Component("/test")
public class ZhouyuBeanNameController implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("jiajia");
}
}
添加了@RequestMapping注解的方法:
@RequestMapping
@Component
public class jiajiaController {
@Autowired
private JiajiaService jiajiaService;
@RequestMapping(method = RequestMethod.GET, path = "/test")
@ResponseBody
public String test(String username) {
return "jiajia";
}
}
一个HandlerFunction对象(以下代码中有两个):
@ComponentScan("com.jiajia")
@Configuration
public class AppConfig {
@Bean
public RouterFunction<ServerResponse> person() {
return route()
.GET("/app/person", request -> ServerResponse.status(HttpStatus.OK).body("Hello GET"))
.POST("/app/person", request -> ServerResponse.status(HttpStatus.OK).body("Hello POST"))
.build();
}
}
什么是HandlerMapping?
HandlerMapping负责去寻找Handler,并且保存路径和Handler之间的映射关系。
因为有不同类型的Handler,所以在SpringMVC中会由不同的HandlerMapping