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

本文介绍了如何从零开始创建一个Springboot项目,主要涉及注册和启动Spring容器以及启动Tomcat。通过模仿Springboot的机制,实现了自定义的Spring容器初始化和Tomcat服务器的启动,允许使用自定义的Springboot依赖来处理HTTP请求。文章最后提到了将项目打包发布并进行测试,证明了手动创建的Springboot能够正常工作。
摘要由CSDN通过智能技术生成

创建自己的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,未来不会太差,只要我们不要太懒就行, 咱们下期见.
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员bling

义父,感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值