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

下载地址: https://download.csdn.net/download/2401_83418369/90675207

一、搭建环境

创建新项目

在pom.xml文件中导入依赖 (一定要刷新Maven)排除内嵌的Tomcat,引入自己指定的Tomcat

复制代码
<?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>com.study</groupId>
    <artifactId>hsp-SpringBoot</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <!--    导入springboot父工程-->
    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.5.3</version>
    </parent>



    <!--    导入web项目场景启动器:会自动导入和web开发相关的所有依赖-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
<!--            排除内嵌的Tomcat-->
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>




<!--        引入指定的Tomcat-->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>8.5.75</version>
        </dependency>
    </dependencies>

</project>

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

创建HspSpringApplication类作为启动springboot的程序

复制代码
package com.study.hspSpringboot;

import org.apache.catalina.startup.Tomcat;

/**
 * 该类相当于是一个springboot启动程序
 */
public class HspSpringApplication {
    //这里会创建Tomcat关联Spring容器
    public static void run(){
        try {
            //创建Tomcat
            Tomcat tomcat = new Tomcat();
            //设置端口
            tomcat.setPort(9090);
            //启动
            tomcat.start();
            //等待请求接入
            System.out.println("======等待连接======");
            tomcat.getServer().await();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

创建HspMainApp作为主程序

复制代码
package com.study.hspSpringboot;

public class HspMainApp {
    public static void main(String[] args) {
        HspSpringApplication.run();
    }
}

当启动springboot程序时,通过netstat -anb命令查询得到

创建一个Bean,一个控制器和一个配置类

Bean对象

hspConfig类

复制代码
package com.study.hspSpringboot.Config;

import com.study.hspSpringboot.bean.Monster;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * @Configuration表示这个类是一个配置类,
 * @ComponentScan("com.study.hspSpringboot")表示要springboot要扫描的路径
 */
@Configuration
@ComponentScan("com.study.hspSpringboot")
public class hspConfig {

    @Bean
    public Monster monster(){
        return new Monster();
    }
}

HiController类

复制代码
package com.study.hspSpringboot.Controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @RestController这个注解表示一个Controller控制器,
 * 也包含@ResponseBody注解的作用(将响应的对象转成json格式的字符串)
 *
 */
@RestController
public class HiController {

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

实现任务阶段2-创建Spring容器 并关联Tomcat

创建HspWebApplicationInitializer 类充当容器对象

复制代码
package com.study.hspSpringboot;

import com.study.hspSpringboot.Config.hspConfig;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

/**
 * 该类是一个Spring容器,完成Bean的创建和依赖注入,前端控制器的分发
 */
public class HspWebApplicationInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        //创建容器对象
        AnnotationConfigWebApplicationContext annotationConfigWebApplicationContext =
                new AnnotationConfigWebApplicationContext();
        //将配置类进行注册到容器(这样才能使配置类的@ComponentScan注解生效,这样才能扫描其它的注解注入到容器)
        annotationConfigWebApplicationContext.register(hspConfig.class);
        //刷新容器(初始化容器,创建Bean对象,注入依赖)
        annotationConfigWebApplicationContext.refresh();
        //创建前端控制器,持有容器
        DispatcherServlet dispatcherServlet =
                new DispatcherServlet(annotationConfigWebApplicationContext);
        //将servlet交给servletContext管理(类似web.xml文件中配置servlet)
        ServletRegistration.Dynamic app =
                servletContext.addServlet("app", dispatcherServlet);
        //当Tomcat启动的时候加载
        app.setLoadOnStartup(1);
        //添加映射
        //注意:不要将映射路径写成/*,这种路径会将静态资源也进行拦截,
        // 但是不能正常的匹配映射servlet对象就会报错
        app.addMapping("/");
    }
}

HspSpringApplication 类中添加工程路径联系该项目

复制代码
package com.study.hspSpringboot;

import org.apache.catalina.startup.Tomcat;

/**
 * 该类相当于是一个springboot启动程序
 */
public class HspSpringApplication {
    //这里会创建Tomcat关联Spring容器
    public static void run(){
        try {
            //创建Tomcat
            Tomcat tomcat = new Tomcat();
            //将Tomcat关联该springboot项目
            //hsp_springboot是工程路径
            //C:\Users\DELL\IdeaProjects\hsp-SpringBoot项目路径
            //当Tomcat启动时通过浏览器访问该工程路径就可以访问该项目
            tomcat.addWebapp("/hsp_springboot","C:\\Users\\DELL\\IdeaProjects\\hsp-SpringBoot");
            //设置端口
            tomcat.setPort(9090);
            //启动
            tomcat.start();
            //等待请求接入
            System.out.println("======等待连接======");
            tomcat.getServer().await();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

运行该springboot程序

解决:在pom.xml文件中引入依赖 (刷新)

复制代码
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jasper</artifactId>
            <version>8.5.75</version>
        </dependency>

通过浏览器发送请求得到

相关推荐
CHQIUU1 小时前
Java 设计模式心法之第4篇 - 单例 (Singleton) 的正确打开方式与避坑指南
java·单例模式·设计模式
碎梦归途1 小时前
23种设计模式-结构型模式之享元模式(Java版本)
java·开发语言·jvm·设计模式·享元模式
Xiaoyu Wang1 小时前
Go协程的调用与原理
开发语言·后端·golang
xixingzhe21 小时前
docker转移镜像
运维·docker·容器
backRoads1 小时前
docker部署springboot(eureka server)项目
spring boot·docker·eureka
lozhyf1 小时前
Eureka搭建
java·spring cloud
幽络源小助理2 小时前
SpringBoot民宿管理系统开发实现
java·spring boot·springboot·民宿系统
东阳马生架构2 小时前
Nacos简介—1.Nacos使用简介
java
爱发飙的蜗牛2 小时前
springboot--web开发请求参数接收注解
java·spring boot·后端
码熔burning2 小时前
【MQ篇】RabbitMQ之工作队列模式!
java·分布式·rabbitmq·mq