前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >手写模拟SpringBoot核心流程(一):实现极简一个SpringBoot——模拟SpringBoot启动过程

手写模拟SpringBoot核心流程(一):实现极简一个SpringBoot——模拟SpringBoot启动过程

作者头像
鳄鱼儿
发布2024-05-21 15:38:48
760
发布2024-05-21 15:38:48
举报

前言

Spring Boot 是一个开源的框架,用于简化 Spring 应用程序的开发和部署。它建立在 Spring Framework 的基础上,内置了web服务器——tomcat和jetty,使得 Spring 应用的构建变得更加快速、简单和可维护。

本文通过实现一个SpringBoot,学习SpringBoot是如何进行工作的。

创建两个模块

实现SpringBoot-模块.png
实现SpringBoot-模块.png
  • springboot:模拟实现springboot框架
  • user:测试调用实现的springboot架构的用户业务系统

引入依赖包

  • SpringBoot基于Spring架构,需要在springboot模块中依赖Spring
  • SpringBoot也支持Spring MVC功能,依赖Spring MVC和Tomcat等

在SpringBoot模块中要添加以下依赖。

代码语言:javascript
复制
<?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">  
    <parent>  
        <artifactId>simulate-springboot</artifactId>  
        <groupId>org.example</groupId>  
        <version>1.0-SNAPSHOT</version>  
    </parent>  
    <modelVersion>4.0.0</modelVersion>  
  
    <artifactId>springboot</artifactId>  
  
    <properties>  
        <maven.compiler.source>8</maven.compiler.source>  
        <maven.compiler.target>8</maven.compiler.target>  
    </properties>  
  
    <dependencies>  
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-context</artifactId> 
            <version>5.3.18</version>  
        </dependency>  
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-web</artifactId>  
            <version>5.3.18</version>  
        </dependency>  
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-webmvc</artifactId>  
            <version>5.3.18</version>  
        </dependency>  
        <dependency>  
            <groupId>javax.servlet</groupId>  
            <artifactId>javax.servlet-api</artifactId>  
            <version>4.0.1</version>  
        </dependency>  
        <dependency>  
            <groupId>org.apache.tomcat.embed</groupId>  
            <artifactId>tomcat-embed-core</artifactId>  
            <version>9.0.60</version>  
        </dependency>  
    </dependencies>  
  
</project>

对于user模块,添加springboot模块即可

代码语言:javascript
复制
<?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">  
    <parent>  
        <artifactId>simulate-springboot</artifactId>  
        <groupId>org.example</groupId>  
        <version>1.0-SNAPSHOT</version>  
    </parent>  
    <modelVersion>4.0.0</modelVersion>  
  
    <artifactId>user</artifactId>  
  
    <properties>  
        <maven.compiler.source>8</maven.compiler.source>  
        <maven.compiler.target>8</maven.compiler.target>  
    </properties>  
  
    <dependencies>  
        <dependency>  
            <groupId>org.example</groupId>  
            <artifactId>springboot</artifactId>  
            <version>1.0-SNAPSHOT</version>  
        </dependency>  
    </dependencies>  
  
</project>

实现SpringBoot简单功能

以下代码若无特别说明则均在springboot模块中,具体位置请查看项目文件结构。

@BerSpringBootApplication注解

代码语言:javascript
复制
package com.ber.springboot;  
  
import org.springframework.context.annotation.ComponentScan;  
import org.springframework.context.annotation.Configuration;  
  
import java.lang.annotation.ElementType;  
import java.lang.annotation.Retention;  
import java.lang.annotation.RetentionPolicy;  
import java.lang.annotation.Target;  
  
/**  
 * @Author 鳄鱼儿  
 * @Description TODO  
 * @date 2023/8/19 14:05  
 * @Version 1.0  
 */
@Target(ElementType.TYPE)  
@Retention(RetentionPolicy.RUNTIME)  
@Configuration  
@ComponentScan  
public @interface BerSpringBootApplication {  
}

BerSpringApplication启动类

代码语言:javascript
复制
package com.ber.springboot;  
  
import org.apache.catalina.*;  
import org.apache.catalina.connector.Connector;  
import org.apache.catalina.core.StandardContext;  
import org.apache.catalina.core.StandardEngine;  
import org.apache.catalina.core.StandardHost;  
import org.apache.catalina.startup.Tomcat;  
import org.springframework.web.context.WebApplicationContext;  
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;  
import org.springframework.web.servlet.DispatcherServlet;  
  
/**  
 * @Author 鳄鱼儿  
 * @Description TODO  
 * @date 2023/8/19 14:08  
 * @Version 1.0  
 */  
public class BerSpringApplication {  
    public static void run(Class clazz) {  
        // 1. 创建Spring 容器  
        AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();  
        applicationContext.register(clazz);  
        applicationContext.refresh();  
  
        // 2. 创建并启动Tomcat  
        startTomcat(applicationContext);  
    }  
  
    private static void startTomcat(WebApplicationContext applicationContext) {  
        // 2.1 创建tomcat对象  
        Tomcat tomcat = new Tomcat();  
  
        Server server = tomcat.getServer();  
        Service service = server.findService("Tomcat");  
  
        Connector connector = new Connector();  
        // 设置默认tomcat启动端口  
        connector.setPort(8023);  
  
        Engine engine = new StandardEngine();  
        engine.setDefaultHost("localhost");  
  
        Host host = new StandardHost();  
        host.setName("localhost");  
  
        String contextPath = "";  
        Context context = new StandardContext();  
        context.setPath(contextPath);  
        context.addLifecycleListener(new Tomcat.FixContextListener());  
  
        host.addChild(context);  
        engine.addChild(host);  
  
        service.setContainer(engine);  
        service.addConnector(connector);  
  
        // 2.2 创建DispatcherServlet对象,并与Spring容器绑定,并将DispatcherServlet对象添加至Tomcat中  
        tomcat.addServlet(contextPath, "dispatcher", new DispatcherServlet(applicationContext));  
        context.addServletMappingDecoded("/*", "dispatcher");  
  
        // 2.3 启动tomcat  
        try {  
            tomcat.start();  
        } catch (LifecycleException e) {  
            e.printStackTrace();  
        }  
    }  
}

run方法实现

user模块中Controller方法被浏览器请求时,就需要run方法去启动一个tomcat,并需要通过一个Servlet接收所有的请求,并将请求分发给相应的Controller进行处理。

在Spring MVC中,DispatcherServlet就起到这个前端控制器的作用。DispatcherServlet需要绑定一个Spring容器,当DispatcherServlet接收到请求后,就可以从绑定的Spring容器中找到所匹配的Controller,并执行对应的方法。

因此,在run方法中实现了:

  1. 创建一个Spring容器
  2. 创建并启动Tomcat
    1. 创建tomcat对象
    2. 创建DispatcherServlet对象,并与Spring容器绑定,并将DispatcherServlet对象添加至Tomcat中
    3. 启动Tomcat
创建spring容器

创建了一个AnnotationConfigApplicationContext容器,并通过传入的clazz作为容器的配置类。

那么,是如何将clazz作为配置类的呢?

在user模块中,UserApplication启动类是这样的。

代码语言:javascript
复制
package com.ber.user;  
  
import com.ber.springboot.BerSpringApplication;  
import com.ber.springboot.BerSpringBootApplication;  
  
/**  
 * @Author 鳄鱼儿  
 * @Description TODO  
 * @date 2023/8/19 14:10  
 * @Version 1.0  
 */  
@BerSpringBootApplication  
public class UserApplication {  
  
    public static void main(String[] args) {  
        BerSpringApplication.run(UserApplication.class);  
    }  
}

将UserApplication.class传入run方法,UserApplication类就是AnnotationConfigWebApplicationContext容器的配置类。

配置过程为:

SpringBoot的run方法配置类过程.png
SpringBoot的run方法配置类过程.png

在Spring容器AnnotationConfigWebApplicationContext创建好后,该容器内部就拥有了user模块下启动类所在包路径下的Bean。

创建并启动Tomcat

在startTomcat()方法中,创建了tomcat对象,并对tomcat进行配置,如默认端口8023,创建和配置 Tomcat 引擎和主机等。然后再创建DispatcherServlet对象,并与Spring容器绑定,并将DispatcherServlet对象添加至Tomcat中。

当运行user模块的UserApplication启动类时,调用BerSpringApplication类中的run方法,所以在run方法中调用startTomcat()方法。

到此,就可以试着运行BerSpringBoot了,可以看到已经成功启动tomcat,并成功访问到了 http://localhost:8023/tes

极简SpringBoot实现效果.png
极简SpringBoot实现效果.png
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
    • 创建两个模块
      • 引入依赖包
      • 实现SpringBoot简单功能
        • @BerSpringBootApplication注解
          • BerSpringApplication启动类
            • run方法实现
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档