SpringMVC流程
主要组件:
-
DispatcherServlet:SpringMVC提供,我们需要使用web.xml配置使其生效,它是整个流程处理的核心,所有请求都经过它处理和分发。
-
HandlerMapping:SpringMVC提供,我们需要进行IoC配置,使其加入到IoC容器。它内部缓存handler(controller方法),和handler访问路径数据,被DispatcherServlet调用,用于查找路径对应的handler。
-
HandlerAdapter:SpringMVC提供,我们需要进行IoC配置,使其加入到IoC容器。它可以处理请求参数和处理响应数据,以及调用handler。每次DispatcherServlet都是通过调用HandlerAdapter来间接调用 handler,它是 DispatcherServlet和 handler之间的适配器。
-
Handler:又称为处理器,它是controller内部方法的简称,由我们自己定义,用来接收参数,向后调用业务,最终返回响应结果。
-
ViewResolver:SpringMVC提供,我们需要进行IoC配置,使其加入到IoC容器。视图解析器主要作用是简化模板视图页面查找,如果handler只返回json数据,不返回页面,那么就不需要视图解析器。
1.基本流程
-
导入依赖
spring-context、servlet(jakarta.jakartaee-web-api)、spring-webmvc
<properties> <spring.version>6.0.6</spring.version> <servlet.api>9.1.0</servlet.api> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!-- springioc相关依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <!-- web相关依赖 --> <!-- 在 pom.xml 中引入 Jakarta EE Web API 的依赖 --> <!-- 在 Spring Web MVC 6 中,Servlet API 迁移到了 Jakarta EE API,因此在配置 DispatcherServlet 时需要使用 Jakarta EE 提供的相应类库和命名空间。错误信息 “‘org.springframework.web.servlet.DispatcherServlet’ is not assignable to ‘javax.servlet.Servlet,jakarta.servlet.Servlet’” 表明你使用了旧版本的 Servlet API,没有更新到 Jakarta EE 规范。 --> <dependency> <groupId>jakarta.platform</groupId> <artifactId>jakarta.jakartaee-web-api</artifactId> <version>${servlet.api}</version> <scope>provided</scope> </dependency> <!-- springwebmvc相关依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> </dependencies>
-
创建Controller类,在其中定义handler,handler需要配置到 HandlerMapping中
用 @RequestMapping 注解将handler注册到 HandlerMapping中,值就是访问该handler的地址
@ResponseBody 注解表示直接返回字符串,不去找视图解析器
package com.ztone.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class HelloController { @RequestMapping("spring/hello") @ResponseBody public String helloHandler(){ return "hello springmvc"; } }
-
准备spring配置类,将handler所在的Controller、HandlerMapping、HandlerAdapter配置到ioc容器
package com.ztone.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; @Configuration @ComponentScan("com.ztone.controller") public class MvcConfig { //配置 HandlerMapping 和 HandlerAdapter @Bean public RequestMappingHandlerMapping handlerMapping(){ return new RequestMappingHandlerMapping(); } @Bean public RequestMappingHandlerAdapter handlerAdapter(){ return new RequestMappingHandlerAdapter(); } }
准备好配置类后,还需要一个ioc容器。通过springmvc 初始化类创建ioc容器
-
创建
该类会加载spring的配置类创建ioc容器,会指定DispatcherServlet的访问地址,他相当于替代了web.xml
该类需要继承 AbstractAnnotationConfigDispatcherServletInitializer,重写如下方法:
-
getServletConfigClasses
设置项目对应的配置类
-
getServletMappings
配置springmvc内部自带的servlet的访问地址,否则需要自己在web.xml 中用servlet标签声明DispaterchServlet,并用servlet-mapping 配置路径
package com.ztone.config; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class SpringMvcInit extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class[0]; } @Override protected Class<?>[] getServletConfigClasses() { return new Class[]{MvcConfig.class}; } @Override protected String[] getServletMappings() { return new String[]{"/"}; } }
-
-
部署到tomcat,注意tomcat的版本必须是 10+
2. springmvc初始化类原理
在上面的springmvc初始化类中可以创建ioc容器,以及配置DispatcherServlet
它能够在服务器一启动就执行这些操作的原因是:继承了AbstractAnnotationConfigDispatcherServletInitializer类
-
AbstractAnnotationConfigDispatcherServletInitializer继承自
-
AbstractDispatcherServletInitializer 继承自
-
AbstractContextLoaderInitializer继承自
-
WebApplicationInitializer
这个接口就是 服务器启动时会执行 onStartup 方法
-
-
-
AbstractDispatcherServletInitializer 也实现了onStartup方法,并且在里面调用了 registerDispatcherServlet()
这个方法调用了 创建 ioc 容器 和 创建DispatcherServlet 的方法
在 createServletApplicationContext 方法中 创建了 ioc容器,并且调用了 getServletConfigClasses,这个方法就是被我们自己创建的初始化类重写了
除了创建ioc容器以及创建DispatcherServlet 两个方法之外,还有一个方法是 getRootConfigClasses
这个方法就是创建 service和 dao层的ioc容器方法