SpringMVC源码深度解析之SpringServletContainerInitializer原理分析 4年前

SpringMVC源码深度解析之SpringServletContainerInitializer原理分析

SpringMVC

Servlet与SpringMVC之间的关系

快速搭建Servlet环境

javax.servlet javax.servlet-api 3.1.0 javax.servlet.jsp javax.servlet.jsp-api 2.3.1

servlet线程是否安全?

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

ServletContainerInitializer接口

案例演示:

@HandlesTypes(value = MyHandlesType.class)//该注解声明的类,会被注入到set中,如果没有合适的类,set为null 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框架

org.springframework spring-webmvc 5.0.5.RELEASE javax.servlet javax.servlet-api 3.1.0 javax.servlet.jsp javax.servlet.jsp-api 2.3.1

springmvc是如何实现无web.xml配置,靠的就是****ServletContainerInitializer

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源码分析

SpringServletContainerInitializer:

进入:org.springframework.web.SpringServletContainerInitializer

@HandlesTypes({WebApplicationInitializer.class}) public class SpringServletContainerInitializer implements ServletContainerInitializer { public SpringServletContainerInitializer() { } public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException { ... }

SpringServletContainerInitializer 为spring中实现ServletContainerInitializer接口的唯一类,该类主要是从容器获取实现WebApplicationInitializer的类,并且按照次序****(javax.annotation.Priority)调用其onStartup方法

我们定义的WebInitializer实现了****WebApplicationInitializer接口

public class WebInitializer implements WebApplicationInitializer { public void onStartup(javax.servlet.ServletContext servletContext) throws ServletException { .... } }

原理:实现了****WebApplicationInitializer 接口的类会被Spring初始化;由于web项目中不能使用spi机制(未定位),所以如果需要动态添加servlet、filter和listener,就可以实现该接口,交由spring初始化。

springmvc是如何替代web.xml

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

debug:可以看到****WebApplicationInitializer子类有我们自定义的WebInitializer

本文参考:

蚂蚁课堂:http://www.mayikt.com/

文档https://docs.oracle.com/javaee/7/api/javax/servlet/ServletContainerInitializer.html?is-external=true

轩辕熠行
你已经不是我的狗了。
3
发布数
1
关注者
1667
累计阅读

热门教程文档

Vue
25小节
Javascript
24小节
10.x
88小节
Rust
84小节
PHP
52小节
广告