SpringMVC源码深度解析之Servlet与SpringMVC关系

Servlet与SPringMVC之间的关系

SpringMVC基于Servlet进行封装的

快速搭建Servlet环境

<dependencies>
  <!-- 添加Servlet支持 -->
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
  </dependency>
  <dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>2.3.1</version>
  </dependency>
</dependencies>

servlet线程是否安全?

不安全,构造函数只执行一次

ServletContainerInitializer接口

在web容器启动时为提供给第三方组件机会做一些初始化的工作,例如注册servlet或者filtes等,servlet规范中通过ServletContainerInitializer实现此功能。 每个框架要使用ServletContainerInitializer就必须在对应的jar包的META-INF/services 目录创建一个名为javax.servlet.ServletContainerInitializer的文件,文件内容指定具体的ServletContainerInitializer实现类。 1、Servlet容器启动会扫描,当前应用里面每一个jar包的 ServletContainerInitializer的实现 2、提供ServletContainerInitializer的实现类; 必须绑定在,META-INF/services/javax.servlet.ServletContainerInitializer 文件的内容就是ServletContainerInitializer实现类的全类名; META-INF:tomcat默认就会去读取的

@HandlesTypes(value = MyHandlesType.class)
public class MyServletContainerInitializer implements ServletContainerInitializer {

    /**
     * @param set            感兴趣类型 也就是MyHandlesType 所有子类型
     * @param servletContext
     * @throws ServletException
     */
    public void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException {
        // 1.打印所有感兴趣的类型
        for (Class<?> c : set) {
            System.out.println(c);
        }
        // 2.servletContext 手动注册过滤器、servlet、监听器
        ServletRegistration.Dynamic payServlet = servletContext.addServlet("payServlet", new PayServlet());
        payServlet.addMapping("/pay");
    }
}

基于注解方式构建SpringMVC框架

<dependencies>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.0.5.RELEASE</version>
  </dependency>
  <!-- 添加Servlet支持 -->
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
  </dependency>
  <dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>2.3.1</version>
  </dependency>
</dependencies>

springmvc是如何实现无web.xml配置

SpringServletContainerInitializer的作用:加载一些第三方的依赖信息

@RestController
public class IndexController {

    @RequestMapping(value = "/",produces="text/html;charset=UTF-8")
    public String index() {
        return "success...";
    }
    /**
     * springmvc环境的时候需要配置那些东西?
     * SpringMVC启动的时候如何实现没有web.xml
     */
}
@Configuration
@ComponentScan("com.mayikt.controller")
@EnableWebMvc
public class SpringMvcConfig {
    //@EnableWebMvc 等于开启SpringMVC注解方式
    //@Configuration xml
    // @ComponentScan("com.mayikt.controller") mvc 扫包范围
    //DispatcherServlet
}
public class WebInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        // 1.启动SpringMVC 容器 类注入到Spring中
        AnnotationConfigWebApplicationContext app = new AnnotationConfigWebApplicationContext();// 启动SpringMVC Web
        // 2.注入我们的springmvc 的配置文件
        app.register(SpringMvcConfig.class);
        // 3. 将我们的DispatcherServlet 注入到 serlvet容器中
        ServletRegistration.Dynamic dynamic = servletContext.addServlet("dispatcher", new DispatcherServlet(app));
        // 4.填写url路径映射
        dynamic.addMapping("/");
        dynamic.setLoadOnStartup(1);// 优先级最高表示 最早被加载
    }
    // 基本配置已经ok呢? web.xml ? 使用WebApplicationInitializer 替代web.xml
    //为什么这个类WebInitializer 不需要注解呢? 能够自动的找到该类呢、
}

SpringServletContainerInitializer源码分析

1.spring-web依赖jar包

SpringServletContainerInitializer会提供SpringMVC实现初始化操作

WebInitializer实现了WebApplicationInitializer

原理:servlet容器在初始化的时候会加载到这个SpringServletContainerInitializer

后找HandlesTypes子类传 回调传递 servletContext

springmvc是如何替代web.xml

使用:SpringServletContainerInitializer 提供给SpringMVC实现初始化

debug:

本文参考:

蚂蚁课堂

http://www.mayikt.com/

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券