springboot系列六: springboot底层机制实现 下

实现SpringBoot底层机制[Tomcat启动分析 + Spring容器初始化 + Tomcat如何关联Spring容器]

  • 实现任务阶段1-创建Tomcat, 并启动
    • 🥦说明:创建Tomcat, 并启动
    • 🥦分析+代码实现
    • 🥦完成测试
  • 实现任务阶段2-创建Spring容器
    • 🥦说明:创建Spring容器
    • 🥦分析+代码实现
  • 实现任务阶段3-将Tomcat 和 Spring容器关联, 并启动Spring容器
    • 🥦说明:将Tomcat 和 Spring容器关联, 并启动Spring容器
    • 🥦分析+代码实现
    • 🥦完成测试
    • 🥦注意事项和细节
    • 在这里插入图片描述

在这里插入图片描述


⬅️ 上一篇: springboot系列五: springboot底层机制实现 上


🎉 欢迎来到 springboot系列六: springboot底层机制实现 下 🎉

在本篇文章中,我们将继续深入探讨 Spring Boot 的底层机制。通过进一步理解这些底层机制,您可以更加全面地掌握 Spring Boot 的工作原理,并在实际项目中灵活运用。


🔧 本篇需要用到的项目: zzw-springboot项目


实现任务阶段1-创建Tomcat, 并启动

🥦说明:创建Tomcat, 并启动

🥦分析+代码实现

1.修改E:\idea_project\zzw_springboot\zzw-springboot\pom.xml

<!--导入web项目场景启动器: 会自动导入和web开发相关的所有依赖[库/jar]
后面还会说明spring-boot-starter-web 到底引入哪些相关依赖-->
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><!--因为我们自己要创建Tomcat对象, 并启动.因此我们先排除 内嵌的 spring-boot-starter-tomcat--><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions></dependency><!--我们指定tomcat版本, 引入tomcat依赖/库1.使用指定的tomcat 8.5.75, 请小伙伴也引入这个版本2.如果我们引入自己指定的tomcat, 一定要记住把前面spring-boot-starter-tomcat排除3.如果你不排除, 会出现 GenericServlet Not Found 的错误提示.--><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-core</artifactId><version>8.5.75</version></dependency>
</dependencies>

2.创建src/main/java/com/zzw/zzwspringboot/ZzwSpringApplication.java

public class ZzwSpringApplication {//这里我们会创建Tomcat对象, 并关联Spring容器, 并启动public static void run() {try {//创建Tomcat对象Tomcat tomcat = new Tomcat();//设置9090端口tomcat.setPort(9090);//启动, 就会在9090端口监听tomcat.start();//等待请求接入System.out.println("====9090 等待请求接入====");tomcat.getServer().await();} catch (Exception e) {throw new RuntimeException(e);}}
}

3.主程序src/main/java/com/zzw/zzwspringboot/ZzwMainApp.java

//主程序
public class ZzwMainApp {public static void main(String[] args) {//启动ZzwSpringBoot项目/程序ZzwSpringApplication.run();}
}

🥦完成测试

1.运行效果
在这里插入图片描述

2.浏览器请求 http://localhost:9090/, 这时没有返回信息, 因为还没有写Controller.
在这里插入图片描述

3.管理员权限运行cmd窗口, 输入netstat -anb. 证明9090端口真的在监听.

在这里插入图片描述

实现任务阶段2-创建Spring容器

🥦说明:创建Spring容器

🥦分析+代码实现

1.新建src/main/java/com/zzw/zzwspringboot/bean/Monster.java, 做一个测试Bean

public class Monster {
}

2.新建src/main/java/com/zzw/zzwspringboot/controller/ZzwHiController.java, 作为Controller

@RestController
public class ZzwHiController {@RequestMapping("/hi")public String hi() {return "hi ZzwHiController";}
}

3.新建src/main/java/com/zzw/zzwspringboot/config/ZzwConfig.java, 作为Spring的配置文件

/*** ZzwConfig 配置类 作为Spring的配置文件* 这里有一个问题, 容器怎么知道要扫描哪些包 ?=> 一会代码体现** 在配置类中可以指定要扫描的包: @ComponentScan("com.zzw.zzwspringboot")*/
@Configuration
@ComponentScan("com.zzw.zzwspringboot")
public class ZzwConfig {//注入Bean - monster 对象到Spring容器@Beanpublic Monster monster() {return new Monster();}
}

4.新建src/main/java/com/zzw/zzwspringboot/ZzwWebApplicationInitializer.java

/*** 解读* 1.创建我们的Spring容器, Initializer-初始化器* 2.加载/关联Spring容器的配置-按照注解的方式* 3.完成Spring容器配置的bean的创建, 依赖注入* 4.创建前端控制器 DispatcherServlet, 并让其持有Spring容器* 5.当 DispatcherServlet 持有容器, 就可以进行分发映射, 回忆实现SpringMVC底层机制* 6.这里onStartup 是Tomcat调用, 并把ServletContext 对象传入*/
public class ZzwWebApplicationInitializer implements WebApplicationInitializer {@Overridepublic void onStartup(ServletContext servletContext) throws ServletException {System.out.println("startup ...");//加载Spring web application configuration => 容器//自己实现的Spring容器叫做 ZzwSpringApplicationContextAnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();//在ac中, 注册 ZzwConfig.class配置类ac.register(ZzwConfig.class);//刷新ac.refresh();//完成bean的创建和配置//1.创建注册非常重要的前端控制器 DispatcherServlet//2.让DispatcherServlet 持有容器//3.这样就可以进行映射分发, 回忆一下我们自己实现的SpringMVC的机制DispatcherServlet dispatcherServlet = new DispatcherServlet(ac);//返回了ServletRegistration.Dynamic 对象ServletRegistration.Dynamic registration= servletContext.addServlet("app", dispatcherServlet);//当tomcat启动时,加载 dispatcherServletregistration.setLoadOnStartup(1);//拦截请求, 并进行分发处理//这里再提示一下 / 和 /* 的区别registration.addMapping("/");}
}

实现任务阶段3-将Tomcat 和 Spring容器关联, 并启动Spring容器

🥦说明:将Tomcat 和 Spring容器关联, 并启动Spring容器

🥦分析+代码实现

1.修改src/main/java/com/zzw/zzwspringboot/ZzwSpringApplication.java

public class ZzwSpringApplication {//这里我们会创建Tomcat对象, 并关联Spring容器, 并启动public static void run() {try {//创建Tomcat对象Tomcat tomcat = new Tomcat();//1. 让tomcat可以将请求转发到spring web容器, 因此需要进行关联//2. "/zzwboot" 就是我们项目的 application context, 就是我们原来配置tomcat时, 指定的 application context//3. "E:\idea_project\zzw_springboot\zzw-springboot" 指定项目的目录tomcat.addWebapp("/zzwboot", "E:\\idea_project\\zzw_springboot\\zzw-springboot");//设置9090端口tomcat.setPort(9090);//启动, 就会在9090端口监听tomcat.start();//等待请求接入System.out.println("====9090 等待请求接入====");tomcat.getServer().await();} catch (Exception e) {throw new RuntimeException(e);}}
}

2.debug运行一下, 这时会报错, 解决方案

在这里插入图片描述

refresh()负责注入初始化相关bean, 在未执行refresh方法前, spring容器是没有bean的

在这里插入图片描述

初始化后, 容器中有了bean文件

在这里插入图片描述

🥦完成测试

1.拿掉断点, 运行程序

2.浏览器请求 http://localhost:9090/zzwboot/hi
在这里插入图片描述

🥦注意事项和细节

1.如果启动包异常, 如下:
严重: Servlet [jsp] in web application [/zzwboot] threw load() exception
java.lang.ClassNotFoundException: org.apache.jasper.servlet.JspServlet

2.解决方案: 引入对应版本的jasper包即可, 修改E:\idea_project\zzw_springboot\zzw-springboot\pom.xml

<dependency><groupId>org.apache.tomcat</groupId><artifactId>tomcat-jasper</artifactId><version>8.5.75</version>
</dependency>

在这里插入图片描述

🔜 下一篇预告: springboot系列七: Lombok注解,Spring Initializr,yaml语法


📚 目录导航 📚

  1. springboot系列一: springboot初步入门
  2. springboot系列二: sprintboot依赖管理
  3. springboot系列三: sprintboot自动配置
  4. springboot系列四: sprintboot容器功能
  5. springboot系列五: springboot底层机制实现 上
  6. springboot系列六: springboot底层机制实现 下
  7. springboot系列七: Lombok注解,Spring Initializr,yaml语法

💬 读者互动 💬
在探索 Spring Boot 底层机制的过程中,您有哪些新的发现或疑问?欢迎在评论区留言,让我们一起讨论吧!😊


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/40009.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

H5项目使用vant组件的手机号校验

前言&#xff1a; 在开发h5项目的时候遇到手机号校验&#xff0c;原本想采用后台管理那种校验方式&#xff08;validator函数写校验手机号逻辑&#xff09;猛然间发现&#xff0c;可以在使用行内使用pattern属性 用法如下 <van-form submit"onSubmit"><van-…

bug,属性注入时为null

因为在使用拦截器时使用的是new的这个类放容器的 解决方法&#xff1a; 使用有参构造器&#xff0c;在new对象时传入值

Spring MVC数据绑定和响应——页面跳转(三)返回值为ModelAndView类型的页面跳转

一、ModelAndView对象组成部分 使用方法的返回值可以设定跳转的逻辑视图名称&#xff0c;使用Model等对象实现页面跳转时传输数据。除此之外&#xff0c;Spring MVC还提供了兼顾视图和数据的对象ModelAndView&#xff0c;ModelAndView对象包含视图相关内容和模型数据两部分&…

鸿蒙开发设备管理:【@ohos.sensor (传感器)】

传感器 说明&#xff1a; 本模块首批接口从API version 8开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import sensor from ohos.sensor;sensor.on ACCELEROMETER on(type: SensorType.SENSOR_TYPE_ID_ACCELEROMETER, callback: C…

PolyGen: An Autoregressive Generative Model of 3D Meshes代码polygen_encoder.py解读

论文&#xff1a;PolyGen: An Autoregressive Generative Model of 3D Meshes 首先阅读transformer铺垫知识《Torch中Transformer的中文注释》。 以下为Encoder部分&#xff0c;很简单&#xff0c;小学生都会&#xff1a; from typing import Optional import pdbimport tor…

mxd的地图文件 像百度地图那样在vue页面上展示出来

要在Vue页面上展示MXD地图文件&#xff0c;可以使用一些开源的JavaScript库来实现。以下是一种可能的方法&#xff1a; 1. 安装ArcGIS API for JavaScript&#xff1a;在Vue项目中使用ArcGIS API for JavaScript可以轻松地加载和展示地图。在命令行中运行以下命令来安装该库&a…

HexPlane: A Fast Representation for Dynamic Scenes(总结图)

图1。用于动态三维场景的 Hex刨面。我们没有从深度 MLP 中回归颜色和不透明度&#xff0c;而是通过 HexPlann 显式地计算时空点的特征。配对一个微小的 MLP&#xff0c;它允许以上100倍加速匹配的质量。 图2。方法概述。Hex刨包含六个特征平面&#xff0c;跨越每对坐标轴(例如…

PyTorch计算机视觉实战:目标检测、图像处理与深度学习

本书基于真实数据集&#xff0c;全面系统地阐述现代计算机视觉实用技术、方法和实践&#xff0c;涵盖50多个计算机视觉问题。全书分为四部分&#xff1a;一部分介绍神经网络和PyTorch的基础知识&#xff0c;以及如何使用PyTorch构建并训练神经网络&#xff0c;包括输入数据缩放…

【前端VUE】VUE3第一节—vite创建vue3工程

什么是VUE Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。无论是简单还是复杂的界面&#xff0…

深入了解自动化:聊聊什么项目适合做自动化测试?

自动化测试 什么是自动化测 什么是自动化测试&#xff1f; 随着软件产业的不断发展&#xff0c;市场对软件周期的要求越来越高&#xff0c;于是催生了各种开发模式&#xff0c;如大家熟知的敏捷开发&#xff0c;从而对测试提出了更高的要求。此时&#xff0c;产生了自动化测试…

启航IT之旅:高考假期预习指南

标题&#xff1a;启航IT之旅&#xff1a;高考假期预习指南 随着高考的落幕&#xff0c;许多有志于IT领域的学子们即将踏上新的学习旅程。这个假期&#xff0c;是他们探索IT世界的黄金时期。本文将为准IT新生们提供一份全面的预习指南&#xff0c;帮助他们为未来的学习和职业生…

008 数组队列(lua)

文章目录 初步array.luaarrayqueue.lua 修改(封装)array.luaarrayqueue.lua测试&#xff08;直接在 arrayqueue.lua 文件的末尾添加&#xff09; 修改(本身就是动态扩容)array.luaarrayqueue.lua 循环队列LoopQueue.lua 初步 array.lua Java是一种静态类型、面向对象的编程语言…

Linux高并发服务器开发(十)反应堆模型和线程池模型

文章目录 1 epoll反应堆2 线程池流程代码 3 复杂版本线程池代码 1 epoll反应堆 文件描述符 监听事件 回调函数 进行封装 创建socket设置端口复用绑定监听创建epoll树将监听文件描述符lfd上epoll树&#xff0c;对应的事件节点包括&#xff1a;文件描述符&#xff0c;事件epoll…

Taogogo Taocms v3.0.2 远程代码执行漏洞(CVE-2022-25578)

前言 CVE-2022-25578 是一个存在于 Taogogo Taocms v3.0.2 中的代码注入漏洞。此漏洞允许攻击者通过任意编辑 .htaccess 文件来执行代码注入。 漏洞详情 漏洞描述&#xff1a;攻击者可以利用此漏洞上传一个 .htaccess 文件到网站&#xff0c;并在文件中注入恶意代码&#xf…

Memcached缓存键命名规范:最佳实践与技巧

引言 Memcached是一个广泛使用的高性能分布式内存缓存系统&#xff0c;它通过键值对的方式存储数据&#xff0c;以提高数据检索速度。正确的缓存键命名对于维护Memcached缓存的效率和可管理性至关重要。本文将详细介绍Memcached缓存键的命名规范和最佳实践。 Memcached缓存键…

苹果手机怎么刷机?适合小白的刷机办法!

自己的苹果手机用时间长了&#xff0c;有些人想要为自己的手机重新刷新一下&#xff0c;但又不知道怎么刷机。不要慌现在就来给大家详细介绍一下苹果手机怎么刷机&#xff0c;希望可以帮助到大家。 iPhone常见的刷机方式&#xff0c;分为iTunes官方和第三方软件两种刷机方式。 …

【elementui】记录解决el-tree开启show-checkbox后,勾选一个叶结点后会自动折叠的现象

第一种解决方案&#xff1a;设置default-expand-keys的值为当前选中的key值即可 <el-treeref"tree"class"checkboxSelect-wrap":data"treeData"show-checkboxnode-key"id":expand-on-click-node"true":props"defau…

游戏云服务器为什么经常卡顿不流畅?

游戏云服务器经常出现卡顿或不流畅的情况可能是由多种因素造成的。以下是一些常见的原因&#xff1a; 网络问题 - 带宽不足&#xff1a;如果服务器的带宽不足以支持高峰时段的所有玩家同时在线&#xff0c;就会导致数据传输缓慢&#xff0c;引起卡顿。 - 网络延迟&#xff1a;网…

第T3周:天气识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、前期工作 本文将采用CNN实现多云、下雨、晴、日出四种天气状态的识别。较上篇文章&#xff0c;本文为了增加模型的泛化能力&#xff0c;新增了Dropout层并…

三、文件操作、错误与异常处理等(爬虫及数据可视化)

三、文件操作、错误与异常处理等&#xff08;爬虫及数据可视化&#xff09; 1&#xff0c;文件操作2&#xff0c;错误与异常 1&#xff0c;文件操作 学习文件操作的相关知识&#xff0c;将一些数据存起来&#xff0c;打开、关闭、读取、写入&#xff0c;重命名、删除等操作在o…