手写自己的Springboot-1-整合tomcat

news2024/11/17 13:51:56

文章目录

    • 创建自己的Springboot
      • 创建项目
      • 注册、启动Spring容器
      • 启动tomcat
    • 引用测试

创建自己的Springboot

首先明确本文章想要达到的目的,就是引入我们自己写的Springboot项目的依赖,无需配置,就可以达到处理普通请求的效果.

这里有一个非常简单的Springboot项目,项目里面就只有一个controller类

在这里插入图片描述

pom中就只引入了一个Springboot的依赖

在这里插入图片描述

当我们启动项目后,访问http://localhost:8080/test就可以得到返回结果.

在这里插入图片描述
那么我们想做的就是把这个依赖换成我们自己写的Springboot项目,也能达到同样的效果.

在这里插入图片描述
那Springboot帮我们做了哪些事情,就可以达到这样的效果呢? 这里其实主要有两件事情.

  1. 注册、启动Spring容器
  2. 启动tomcat

所以接下来,我们就会尝试去做这个东西,手写我们自己的Springboot.

创建项目

这里首先创建了一个Spring项目,因为Springboot肯定是依赖于Spring的.项目总体结构如下:
在这里插入图片描述

启动类BlingSpringApplication,将来使用方就是调用这个run方法去启动我们自己的Springboot的,只不过现在是空的.

在这里插入图片描述
这里也模仿Springboot去定义了一个注解,将来便于调用方进行标识使用.

在这里插入图片描述

pom如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.com.bling</groupId>
    <artifactId>springboot</artifactId>
    <version>1.0-SNAPSHOT</version>


    <dependencies>
<!--        引入一些基础的spring依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.8.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.2.8.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.2.8.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.8.RELEASE</version>
        </dependency>

<!--        servlet依赖-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>

<!--        web容器依赖-->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>9.0.37</version>
        </dependency>

<!--        <dependency>-->
<!--            <groupId>org.eclipse.jetty</groupId>-->
<!--            <artifactId>jetty-server</artifactId>-->
<!--            <version>9.4.51.v20230217</version>-->
<!--        </dependency>-->


    </dependencies>


</project>

注册、启动Spring容器

建好了我们自己的Springboot项目,接下来就需要注册、启动Spring容器了.

其实代码很简单,只有三行.就写在我们的run方法里面.

这里需要注意一下,我们注册,启动Spring容器,需要传入一个类.这个类一般会是启动类.那为什么要传入一个类呢?

  • 其实最主要的就是为了能够解析到一个路径,我们知道springboot会默认扫描一个包路径,将这个包路径下面所有需要的bean都注册到spring容器中
    那这个路径是怎么确定的呢? 其实就是这个传入类所在的包路径.

    会解析这个传入类上的所有注解(包括注解上的注解),然后如果有ComponentScan注解的话,就会进行扫描注入.

public static void run(Class clazz) {
        //new 一个Spring容器对象
        AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
        /**
         * 对spring进行注册,这里为什么要传入一个类?
         *    其实最主要的就是为了能够解析到一个路径,我们知道springboot会默认扫描一个包路径,将这个包路径下面所有需要的bean都注册到spring容器中
         *    那这个路径是怎么确定的呢? 其实就是这个传入类所在的包路径.
         *    会解析这个传入类上的所有注解(包括注解里的注解),然后如果有ComponentScan注解的话,就会进行处理 
         */
        applicationContext.register(clazz);
        //真正扫描路径,初始化bean的步骤
        applicationContext.refresh();

    }

启动tomcat

有了Spring容器,就可以启动tomcat了.

为什么要先初始化Spring容器呢?

因为tomcat作为一个servlet容器, 需要一个servlet.,在SpringMVC中,这个servlet是由DispatcherServlet来实现的,由它进行请求的分发,处理.

而DispatcherServlet是需要Spring容器的,因为tomcat启动后会将所有的请求交给DispatcherServlet去进行处理,DispatcherServlet拿到请求后会根据请求路径去spring容器中找到对应的bean,然后执行对应的方法,然后将结果进行返回.

public class BlingSpringApplication {

    public static void run(Class clazz) {
        //注册,启动Spring容器
        AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
        /**
         * 对spring进行注册,这里为什么要传入一个类?
         *    其实最主要的就是为了能够解析到一个路径,我们知道springboot会默认扫描一个包路径,将这个包路径下面所有需要的bean都注册到spring容器中
         *    那这个路径是怎么确定的呢? 其实就是这个传入类所在的包路径.
         *    会解析这个传入类上的所有注解(包括注解里的注解),然后如果有CompantScan注解的话,就会进行处理
         */
        applicationContext.register(clazz);
        //真正扫描路径,初始化bean的步骤
        applicationContext.refresh();

		//启动tomcat
        startTomcat(applicationContext);


    }

    /**
     * 启动tomcat
     * @param applicationContext
     */
    private static void startTomcat(AnnotationConfigWebApplicationContext applicationContext) {
        Tomcat tomcat = new Tomcat();

        Server server = tomcat.getServer();
        Service service = server.findService("Tomcat");

        //创建链接,绑定端口
        Connector connector = new Connector();
        connector.setPort(8080);

        StandardEngine standardEngine = new StandardEngine();
        standardEngine.setDefaultHost("localhost");

        StandardHost host = new StandardHost();
        host.setName("localhost");

        String contextPath = "";
        StandardContext context = new StandardContext();
        context.setPath(contextPath);
        context.addLifecycleListener(new Tomcat.FixContextListener());

        host.addChild(context);
        standardEngine.addChild(host);

        service.setContainer(standardEngine);
        service.addConnector(connector);

        /**
         * 最主要的一步,需要用到DispatcherServlet,这个是SpringMVC里面的,帮我们进行映射
         * 那DispatcherServlet接收到请求怎么处理的呢?
         *    DispatcherServlet需要一个applicationContext,也就是spring上下文
         *    tomcat启动后会将所有的请求交给DispatcherServlet去进行处理,DispatcherServlet拿到请求后会根据请求路径去spring上下文中
         *    找到对应的bean,然后执行对应的方法,然后将结果进行返回
         *
         *
         */
            tomcat.addServlet(context,"dispatcher",new DispatcherServlet(applicationContext));
        context.addServletMappingDecoded("/*","dispatcher");

        try {
            tomcat.start();
        } catch (LifecycleException e) {
            e.printStackTrace();
        }


    }

}

引用测试

现在我们就可以将自己的Springboot打包,发布到本地仓库,进行使用了.

  1. 替换成我们写的maven依赖

在这里插入图片描述
2. 替换成我们自己的注解和启动类.

在这里插入图片描述
其他保持不变,启动项目,看是否能达到我们想要的结果.

在这里插入图片描述
项目正常启动之后,进行访问. 发现确实可以正常访问.
在这里插入图片描述
至此,我们第一步就完成了,当然,目前是一个非常简单的小功能,还非常的不完善,比如说现在不想用tomcat了,想使用jetty,在Springboot中直接切换依赖就可以了,其他都不用动,就可以启动jetty了,那它又是怎样做到的呢?

这个将在后续的文章中不断揭秘.

今天的分享就到这里了,有问题可以在评论区留言,均会及时回复呀.
我是bling,未来不会太差,只要我们不要太懒就行, 咱们下期见.
在这里插入图片描述

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

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

相关文章

将 Segment Anything 扩展到医学图像领域

文章目录 前言技术交流SAM 拆解分析从医学角度理解 SAM 的效用MedSAM实验总结 前言 SAM 是一种在自然图像分割方面取得成功的模型&#xff0c;但在医学图像分割方面表现不佳。MedSAM 首次尝试将 SAM 的成功扩展到医学图像&#xff0c;并成为用于分割各种医学图像的通用工具。为…

22.网络爬虫—APP数据抓取详讲

网络爬虫—APP数据抓取详讲 Fiddler工作原理安装完成Fiddler后的配置前提条件工具配置 手机数据抓取Fiddler手机端配置手机端操作 实战演示后记 前言&#xff1a; &#x1f3d8;️&#x1f3d8;️个人简介&#xff1a;以山河作礼。 &#x1f396;️&#x1f396;️:Python领域新…

springboot+mybatis搭建maven多模块工程

最近看了一篇博客&#xff0c;选定springbootmybatis作为框架&#xff0c;在idea中搭建maven的多模块工程&#xff0c;下面也再温习一下&#xff0c;并将搭建过程分享出来&#xff0c;供小伙伴们参考。 1、开发工具及系统环境 Idea 2020.3系统环境为win10mysql5.7springboot2.…

GNN学习/GCN学习/GNN环境配置cuda安装/GCN代码展示

参考: A Gentle Introduction to Graph Neural Networks https://distill.pub/2021/gnn-intro/Understanding Convolutions on Graphs https://distill.pub/2021/understanding-gnns/Graph neural networks: A review of methods and applications https://arxiv.org/pdf/1812…

【Java】认识异常

目录 1.异常概念和分类 2.异常的抛出 3.异常的捕获 3.1异常声明throws 3.2异常捕获try-catch 3.3finally 3.4.异常的处理流程 4.自定义异常类 1.异常概念和分类 public class Test {public static void test() {test();}public static void main(String[] args) {Sy…

详解数据集safety-pilot-model-deployment-data

safety-pilot-model-deployment-data这个数据集是由美国交通部的联邦航空管理局&#xff08;FAA&#xff09;和交通运输部&#xff08;DOT&#xff09;主导的“安全试点”&#xff08;Safety Pilot Model Deployment&#xff09;项目所提供的。该项目旨在研究汽车与飞机之间的通…

Vue电商项目--开发Search模块与mockjs模拟数据

Search模块中商品分类与过度动画 现在完成了在/home路由下实现三级导航组件的显示隐藏 通过this.$route.path!/home在搜索页面显示&#xff0c;通过方法鼠标移入移出从而又控制在search路由下的显示隐藏 过渡动画&#xff1a;前提组件|元素必要又v-if| v-show指令才可以进行…

Linux进程状态及优先级

本文已收录至《Linux知识与编程》专栏&#xff01; 作者&#xff1a;ARMCSKGT 演示环境&#xff1a;CentOS 7 进程状态及优先级 前言正文进程状态就绪运行状态R阻塞睡眠状态 S休眠状态D挂起 暂停状态T前台与后台进程待追踪暂停状态t 死亡状态 X僵尸状态 Z 孤儿进程进程优先级查…

nginx(七十三)nginx与Location响应头细节探讨

一 nginx与Location响应头细节探讨 ① 重定向和Location回顾 多种重定向跳转方式的差异 nginx之absolute_redirect、server_name_in_redirect、port_in_redirect 共同控制Location响应头 ② STS响应头导致307重定向 "第一次访问 http://www.baidu.com" 观察…

基于Qt、C++的毕业设计课设数学绘图工具(平面图、图表、立体图绘制-附下载链接)

基于Qt、C的毕业设计课设数学绘图工具&#xff08;平面图、图表、立体图绘制&#xff09; 介绍 这是我的毕业设计&#xff0c;基于Qt Creator 4.11.1&#xff0c;c语言。 效果图如下 点我下载项目源码&#xff08;含打包软件&#xff09; 使用说明 1. 二维函数绘制 开始界面…

python 系列 07 - 基于easyocr的ocr识别

OCR,光学文字识别&#xff0c;对文本资料进行扫描&#xff0c;然后对图像文件进行分析处理&#xff0c;获取文字及版面信息的过程。本示例通过easyocr库来演示。easyocr是一个比较流行的库&#xff0c;支持超过80种语言。安装的时候注意会附带安装torch库&#xff08;一个深度学…

将ROS1和ROS2安装到同一个ubuntu系统中,ROS2安装??????????????

1. 本文测试环境: ubuntu:20.04,虚拟机 ROS1:noetic ROS2:foxy 2. 先说结论 ROS1 与 ROS2 共存,需要考虑三个问题: 1) 不同Ubuntu版本,有不同版本的ROS1和ROS2推荐,尽量不要任性地乱装; 2)ROS1和ROS2安装过程中,是否会出现文件“删改”的问题?目前使用下来,并…

拓扑排序详解(包含算法原理图解、算法实现过程详解、算法例题变式全面讲解等)

前置知识 有向无环图 在图论中&#xff0c;如果一个有向图无法从某个顶点出发经过若干条边回到该点&#xff0c;则这个图是一个有向无环图&#xff08;DAG图&#xff09;。 如图所示。 入度 对于一个有向图&#xff0c;若x点指向y点&#xff0c;则称x点为y点的入度。 出度…

Redis --- 多级缓存

一、什么是多级缓存 传统的缓存策略一般是请求到达Tomcat后&#xff0c;先查询Redis&#xff0c;如果未命中则查询数据库&#xff0c;如图&#xff1a; 存在下面的问题&#xff1a; 请求要经过Tomcat处理&#xff0c;Tomcat的性能成为整个系统的瓶颈Redis缓存失效时&#xff…

python每日一练:硬币划分(多方法详解)

文章目录 前言0、题目一、暴力总是不能解决问题的二、还能更暴力一点三、减少暴力思想四、引入先进思想总结 前言 这题挺有意思的&#xff0c;典型的背包组合问题&#xff0c;虽然没有要求各种组合方式&#xff0c;不过我们可以试试给出组合方式。当然这题不太可能用一行代码解…

STM32 从入门到精通系列讲解 - 总目录

&#x1f466; 作者介绍&#xff1a;Bazinga bingo&#xff0c;专注C语言应用硬核干货分享&#xff0c;潜心修炼&#xff0c;虚心学习&#xff0c;立志做嵌入式相关赛道的Top。 &#x1f4d5; 本文收录于《STM32开发》专栏&#xff0c;包含STM32内部模块介绍、片内资源开发、不…

如何使用bingChat(使用方法+遇到的问题+感受)

文章目录 前言一、如何使用Bing Chat1. 下载new Bing2.重新注册一个microsoft&#xff08;此步骤可略过&#xff0c;如有问题再操作此步骤&#xff09;3. 使用 Bing Chat 二、常见问题1.Chat mode is only available when you have access to the new Bing.2. 网页上没有“聊天…

leetcode 104——二叉树的最大深度

文章目录 题目详情方法一 万能的递归方法二 通过使用层序遍历的方式Java完整代码递归实现非递归实现——借助队列 题目详情 给定一个二叉树&#xff0c;找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 说明: 叶子节点是指没有子节点的节点。 l…

yolov5图像识别voc转yolo代码解析

https://github.com/ultralytics/JSON2YOLO https://blog.csdn.net/qq_51831335/article/details/127237772 目标检测数据集标签转换COCO2VOC、YOLO2VOC、JSON2YOLO <annotation><folder>VOC2007</folder><filename>000001.jpg</filename><s…

x265码控分析

D和R的关系 高分辨率量化 均匀量化&#xff1a;量化区间 ‘ Δ k y k − y k − 1 ‘ \Delta_ky_k-y_{k-1} ‘Δk​yk​−yk−1​‘&#xff0c;近似为常数&#xff1b;p(x)为信源概率密度函数&#xff0c;且 ‘ Δ k ‘ \Delta_k ‘Δk​‘的大小相对于p(x)的变化率充分小&…