springboot 是如何帮我们省去web.xml配置的

简介: 概述最开始使用原生的springmvc时,总是免不了有如下xml配置 spring org.springframework.web.

概述

最开始使用原生的springmvc时,总是免不了有如下xml配置

<!-- Spring MVC配置 -->
<!-- ====================================== -->
<servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>
  

<!-- Spring配置 -->
<!-- ====================================== -->
<listener>
   <listenerclass>
 org.springframework.web.context.ContextLoaderListener
   </listener-class>
</listener>
  

<!-- 指定Spring Bean的配置文件所在目录。默认配置在WEB-INF目录下 -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:config/applicationContext.xml</param-value>
</context-param>

但是,切换到springboot之后,web.xml之类的繁琐的配置基本上都不见了。出于好奇研究了下springboot究竟帮我们做了什么,我们可以免于这样的繁琐配置。

Servlet3.0规范

首先研究的第一点,为什么web.xml不见了。刚开始使用原生servlet(不使用web框架),web.xml就是非常重要的一个配置,无论是servlet、filter、listener都需要在web.xml里面配置下。

但是在servlet3.0里,这个配置得到了简化。可以通过java配置(注解等)省去web.xml配置。

具体servlet3.0的规范这里就不讨论了,说下其中一个非常重要的类。javax.servlet.ServletContainerInitializer

这个类会在web容器启动阶段被回调,可以在onStartup方法里做一些servlet、filter、listener的注册等操作。

/**
Interface which allows a library/runtime to be notified of a web application's startup phase and perform any required programmatic registration of servlets, filters, and listeners in response to it.
*/
public interface ServletContainerInitializer {

    public void onStartup(Set<Class<?>> c, ServletContext ctx)
        throws ServletException; 
}

springboot的实现

首先spring在META-INF/services下配置了这个类,让整个web容器启动后可以找到并启动这个类

img_4aa39bf0a7ea33ae0b3315f2b95fd7cb.png
ServletContainerInitializer配置

SpringServletContainerInitializer

/**
* @HandlesTypes这个注解标明了该ServletContainerInitializer需要在启动时候处理哪些类,
然后服务器会把找到的这些类传到onStartup的第一个参数里

注意这里的类包括所配置类的子类,比如这里配置WebApplicationInitializer,
启动之后,就会把这个WebApplicationInitializer的子类都传进去
*/
@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {
        
    @Override
    public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
            throws ServletException {

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

        //.... 省略容错的一些代码
        initializers.add((WebApplicationInitializer) waiClass.newInstance());
        //.... 
    AnnotationAwareOrderComparator.sort(initializers);
        for (WebApplicationInitializer initializer : initializers) {
            initializer.onStartup(servletContext);
        }
    }

}

startup的逻辑很简单,web容器启动后,调用所有WebApplicationInitializer的onStartup方法。

WebApplicationInitializer 的实现SpringBootServletInitializer

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
   //....
    WebApplicationContext rootAppContext = createRootApplicationContext(
            servletContext);
   //...
}

protected WebApplicationContext createRootApplicationContext(
        ServletContext servletContext) {
    //...
    return run(application);
}

一般使用Springboot的时候,都会继承一个类SpringBootServletInitializer,在这个类的onStartup方法中,启动了整个Spring容器。

本地启动springboot时,我们一般会写一个类似于这样的main方法。


img_54a943038b9625e5004717951c0679fb.png

上述分析也解释了为啥把springboot应用部署到机器上,tomcat能够找到springboot的入口,并启动它。

DispatcherServlet的配置

关于springboot如何加载类并启动的这里就不介绍了。
这里说明下究竟Springboot如何配置DispatcherServlet的


img_9154913ad9619cc7c6c2bc1c5c681dc7.png

1)当类路径下存在DispatcherServlet时候,该配置生效。
2)这个配置会在DispatcherServletAutoConfiguration配置完之后再配置。

DispatcherServletAutoConfiguration配置

img_dd4fa96aba078028d1a81e8692732221.png
img_f59f381a78aceaadf70b93a7eb47dcc4.png

看到这里就是我们非常熟悉的springboot的使用了。springboot在DispatcherServletConfiguration这个类里对DispatcherServlet进行了配置以及注册。

总结

服务器如tomcat在web应用启动后,加载并启动springboot,springboot通过@AutoConfiguration、@Bean、@Conditional等注解自动配置了DispatcherServlet。

img_a3d50ce13153bcb0d9bbf3620b18a9d0.png
丑丑的樱花星
目录
相关文章
|
23天前
【Azure 应用服务】Web App Service 中的 应用程序配置(Application Setting) 怎么获取key vault中的值
【Azure 应用服务】Web App Service 中的 应用程序配置(Application Setting) 怎么获取key vault中的值
|
3天前
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
39 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
|
15天前
|
监控 Apache
HAProxy的高级配置选项-Web服务器状态监测
这篇文章介绍了HAProxy的高级配置选项,特别是如何进行Web服务器状态监测,包括基于四层传输端口监测、基于指定URI监测和基于指定URI的request请求头部内容监测三种方式,并通过实战案例展示了配置过程和效果。
40 8
HAProxy的高级配置选项-Web服务器状态监测
|
16天前
|
SQL XML Java
mybatis :sqlmapconfig.xml配置 ++++Mapper XML 文件(sql/insert/delete/update/select)(增删改查)用法
当然,这些仅是MyBatis功能的初步介绍。MyBatis还提供了高级特性,如动态SQL、类型处理器、插件等,可以进一步提供对数据库交互的强大支持和灵活性。希望上述内容对您理解MyBatis的基本操作有所帮助。在实际使用中,您可能还需要根据具体的业务要求调整和优化SQL语句和配置。
22 1
|
17天前
|
Java Spring Apache
Spring Boot邂逅Apache Wicket:一次意想不到的完美邂逅,竟让Web开发变得如此简单?
【8月更文挑战第31天】Apache Wicket与Spring Boot的集成提供了近乎无缝的开发体验。Wicket以其简洁的API和强大的组件化设计著称,而Spring Boot则以开箱即用的便捷性赢得开发者青睐。本文将指导你如何在Spring Boot项目中引入Wicket,通过简单的步骤完成集成配置。首先,创建一个新的Spring Boot项目并在`pom.xml`中添加Wicket相关依赖。
37 0
|
17天前
|
Java Spring 开发者
Java Web开发新潮流:Vaadin与Spring Boot强强联手,打造高效便捷的应用体验!
【8月更文挑战第31天】《Vaadin与Spring Boot集成:最佳实践指南》介绍了如何结合Vaadin和Spring Boot的优势进行高效Java Web开发。文章首先概述了集成的基本步骤,包括引入依赖和配置自动功能,然后通过示例展示了如何创建和使用Vaadin组件。相较于传统框架,这种集成方式简化了配置、提升了开发效率并便于部署。尽管可能存在性能和学习曲线方面的挑战,但合理的框架组合能显著提升应用开发的质量和速度。
26 0
|
17天前
|
Java 前端开发 Spring
技术融合新潮流!Vaadin携手Spring Boot、React、Angular,引领Web开发变革,你准备好了吗?
【8月更文挑战第31天】本文探讨了Vaadin与Spring Boot、React及Angular等主流技术栈的最佳融合实践。Vaadin作为现代Java Web框架,与其他技术栈结合能更好地满足复杂应用需求。文中通过示例代码展示了如何在Spring Boot项目中集成Vaadin,以及如何在Vaadin项目中使用React和Angular组件,充分发挥各技术栈的优势,提升开发效率和用户体验。开发者可根据具体需求选择合适的技术组合。
28 0
|
19天前
|
JSON Java API
解码Spring Boot与JSON的完美融合:提升你的Web开发效率,实战技巧大公开!
【8月更文挑战第29天】Spring Boot作为Java开发的轻量级框架,通过`jackson`库提供了强大的JSON处理功能,简化了Web服务和数据交互的实现。本文通过代码示例介绍如何在Spring Boot中进行JSON序列化和反序列化操作,并展示了处理复杂JSON数据及创建RESTful API的方法,帮助开发者提高效率和应用性能。
48 0
|
19天前
|
消息中间件 Java Kafka
Spring Boot与模板引擎:整合Thymeleaf和FreeMarker,打造现代化Web应用
【8月更文挑战第29天】这段内容介绍了在分布式系统中起到异步通信与解耦作用的消息队列,并详细探讨了三种流行的消息队列产品:RabbitMQ、RocketMQ 和 Kafka。RabbitMQ 是一个基于 AMQP 协议的开源消息队列系统,支持多种消息模型,具有高可靠性及稳定性;RocketMQ 则是由阿里巴巴开源的高性能分布式消息队列,支持事务消息等多种特性;而 Kafka 是 LinkedIn 开源的分布式流处理平台,以其高吞吐量和良好的可扩展性著称。文中还提供了使用这三种消息队列产品的示例代码。
21 0
|
19天前
|
监控 Java API
Spring Boot中的异步革命:构建高性能的现代Web应用
【8月更文挑战第29天】Spring Boot 是一个简化 Spring 应用开发与部署的框架。异步任务处理通过后台线程执行耗时操作,提升用户体验和系统并发能力。要在 Spring Boot 中启用异步任务,需在配置类上添加 `@EnableAsync` 注解,并定义一个自定义的 `ThreadPoolTaskExecutor` 或使用默认线程池。通过 `@Async` 注解的方法将在异步线程中执行。异步任务适用于发送电子邮件、数据处理、外部 API 调用和定时任务等场景。最佳实践中应注意正确配置线程池、处理返回值和异常、以及监控任务状态,确保系统的稳定性和健壮性。
29 0