SpringMVC流程

SpringMVC流程

 

img

主要组件:

  • 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.基本流程

  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>
  2. 创建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";
        }
    }
  3. 准备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容器

  4. 创建

    该类会加载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[]{"/"};
        }
    }
  5. 部署到tomcat,注意tomcat的版本必须是 10+

 

2. springmvc初始化类原理

在上面的springmvc初始化类中可以创建ioc容器,以及配置DispatcherServlet

它能够在服务器一启动就执行这些操作的原因是:继承了AbstractAnnotationConfigDispatcherServletInitializer类

  • AbstractAnnotationConfigDispatcherServletInitializer继承自

    • AbstractDispatcherServletInitializer 继承自

      • AbstractContextLoaderInitializer继承自

        • WebApplicationInitializer

          这个接口就是 服务器启动时会执行 onStartup 方法

 

 

AbstractDispatcherServletInitializer 也实现了onStartup方法,并且在里面调用了 registerDispatcherServlet()

image-20240815102719698

这个方法调用了 创建 ioc 容器 和 创建DispatcherServlet 的方法

image-20240815102848979

在 createServletApplicationContext 方法中 创建了 ioc容器,并且调用了 getServletConfigClasses,这个方法就是被我们自己创建的初始化类重写了

除了创建ioc容器以及创建DispatcherServlet 两个方法之外,还有一个方法是 getRootConfigClasses

这个方法就是创建 service和 dao层的ioc容器方法

posted @ 2024-08-15 10:58  GrowthRoad  阅读(8)  评论(0编辑  收藏  举报