SpringBoot的web.xml文件在哪里?

每天叫醒你的不是闹钟,而是梦想

01

追溯web.xml

远古时期,使用servlet做web开发的时候,我们需要配置web.xml文件;

近代时期,使用springMVC做web开发的时候,我们需要配置web.xml文件;

现代时期,使用SpringBoot做web开发的时候,我们不需要配置web.xml文件

   这是为什么呢?

02

web.xml干了什么?

要了解SpringBoot为什么不需要配置web.xml文件,我们首先要知道web.xml干了什么,是不是SpringBoot用了什么其他文件代替?

首先我们要从servlet讲起,在servlet-api2.5的时候,我们要注册一个servlet需要引入web.xml,我们需要对每一个请求进行一个类的映射;直到servlet-api3.0的发布,我们注册一个servlet就简单了,只需要引入一个@WebServlet注解。

接着我们进入spring+springmvc(2.5)时代,依旧需要使用web.xml,我们可以了解一下这个时候的web.xml配置文件的内容。

我们去Spring官网查看关于SpringMVC模块提供的web.xml内容

首先是ContextLoaderListener类,该类是指定Spring要加载的配置文件,加载我们的spring配置文件。而在spring的配置文件中,会有

<context:component-scan base-package="com.zero "/>
该行代码的作用是扫描业务类(service,dao层的注解)
接着是我们的DispatcherServlet,该作用是加载spring-mvc的配置文件,在spring-mvc的配置文件中

<context:component-scan base-package=“com.zero.controller”></context:component-scan>
该行代码是扫描映射类(controller的注解)
接着是

1
该配置表示容器启动的时候执行DispatcherServlet的init方法
最后是

/*
拦截请求
总结:web.xml需要做的事情就是 加载spring配置文件,加载springmvc文件,注册一个servlet,拦截请求。

03

SpringMVC5用java代码替代了web.xml

那么我们将刚刚的Spring官网上的内容往上翻

我们可以看到这段代码,上面的最后一行文档告诉我们:

以下Java配置实例注册并初始化DispacherServlet,由Servlet容器自动给检测,也就是说,在SpringMVC5的时候,已经由Java代码代替了web.xml配置文件,那么我们来了解一下官网的这段代码。

public class MyWebApplicationInitializer implements WebApplicationInitializer {

@Override
public void onStartup(ServletContext servletCxt) {

// Load Spring web application configuration 加载spring配置文件
AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
ac.register(AppConfig.class);
ac.refresh();

// Create and register the DispatcherServlet 创建和注册DispatcherServlet
DispatcherServlet servlet = new DispatcherServlet(ac);
ServletRegistration.Dynamic registration = servletCxt.addServlet(“app”, servlet);

registration.setLoadOnStartup(1); //1
registration.addMapping("/app/"); ///app/
}
}
所以在spring5的时候,web.xml配置文件已经完全被Java代码取代。这其实就是一个过渡。

在该配置中,我们可以看到的是MyWebApplicationInitializer 实现了WebApplicationInitializer 这个接口,然后在onStartup方法中实现了配置,那么也就是说WebApplicationInitializer 的实现类只要调用了onStartup方法就可以进行一些初始化。

那么其实在servlet-api3.1的标准中定义了一个规范,如果你想要启动容器的时候定义这么一个配置,那么你需要在某个文件夹下(/META-INF/services/javax.servlet.ServletContainerInitializer)定义一个容器时会回调的类,这个类必须要实现ServletContainerInitializer接口,那么在web容器启动时就会做一些初始化工作,而这些初始化工作是在onStartup方法中执行的。

接下来我们看一下ServletContainerInitializer接口

根据注释:为了支持可以不使用web.xml。提供了ServletContainerInitializer这个接口,该接口通过SPI机制,当web容器启动的时候,会自动添加相应jar包下找到META-INF/services/javax.servlet.ServletContainerInitializer文件中的实现类,将他们实例化。

于是我们找到了这个文件,该文件下有一个实现类,我们进入这个实现类

@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {

@Override
public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
throws ServletException {

 List<WebApplicationInitializer> initializers = new LinkedList<>();

 if (webAppInitializerClasses != null) {
 for (Class<?> waiClass : webAppInitializerClasses) {
    if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
       WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
     try {
         initializers.add((WebApplicationInitializer)
         ReflectionUtils.accessibleConstructor(waiClass).newInstance());
       }catch (Throwable ex) {
         throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
     }
    }
 }

}
那么该实现类就会通过SPI机制,在web容器加载的时候会自动被调用,类上的@handlesTypes注解,它的作用是将感兴趣的一些类注入到ServletContainerInitializerde接口中,而这个类的方法就会扫描到WebApplicationIntializer的实现类,调用它的onStartup方法,从而起到了web.xml的作用。因为我们上面已经说过:WebApplicationInitializer 的实现类只要调用了onStartup方法就可以进行一些初始化,也就是加载了web.xml配置。
————————————————
版权声明:本文为CSDN博主「新时代Java农民工」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zejava/article/details/107039549

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值