SpringBoot(源码解析 + 实现底层机制)

文章目录

    • 1.搭建SpringBoot底层机制开发环境
        • 1.创建maven项目
        • 2.使用Git管理项目(可以略过)
          • 1.创建一个github存储库
          • 2.克隆到本地,复制文件夹的内容
          • 3.粘贴到idea项目文件夹,将其作为本地仓库与远程仓库关联
        • 3.pom.xml 引入父工程和场景启动器
        • 4.编写运行类
        • 5.启动运行类,思考:tomcat怎么启动的?
    • 2.@Configuration机制梳理
        • 1.环境搭建
          • 1.文件目录
          • 2.Dog.java
          • 3.Config.java 注入单例Dog对象
          • 4.MainApp.java测试是否能够获取bean
          • 5.成功获取
        • 2.机制分析
          • 1.简述
          • 2.图解
    • 3.SpringBoot是怎么启动Tomcat的?
        • 1.环境搭建
          • 1.文件目录
          • 2.HiController.java
          • 3.测试访问
        • 2.源码分析
          • 1.需求分析
          • 2.创建容器过程
            • 1.run方法打断点
            • 2.进入
            • 3.进入
            • 4.进入 SpringApplication
            • 5.继续进入
            • 6.放行到创建容器的那个方法
            • 7.进入
            • 8.继续进入
            • 9.下一步
            • 10.跳出回到createApplicationContext()方法
          • 3.找到createWebServer()
            • 1.打断点
            • 2.放行,并查看目前的容器
            • 3.进入并执行到refresh方法
            • 4.进入
            • 5.再进入
            • 6.进入
            • 7.放行到那个断点
            • 8.进入
            • 9.下一步,找到了createWebServer方法
          • 4.启动Tomcat
            • 1.进入
            • 2.放行到断点并进入getWebServer
            • 3.进入
            • 4.直接跳出
            • 5.放行到下一个断点,然后进入
            • 6.进入,给initialize方法下断点
            • 7.进入,给tomcat.start()下断点
            • 8.直接放行,tomcat启动成功
            • 9.回到afterRefresh方法(一直跳出),此时应用程序上下文已经刷新成功
            • 10.查看目前的容器,完成初始化
    • 4.SpringBoot(实现底层机制)
        • 1.创建Tomcat并启动
          • 1.排除pom.xml中的 spring-boot-starter-tomcat并引入指定版本的Tomcat
          • 2.编写SunSpringApplication.java
            • 1.文件目录
            • 2.创建Tomcat对象,关联Spring容器并启动
            • 3.编写SunMainApp.java,启动Tomcat
            • 4.结果展示
        • 2.创建Spring容器
          • 1.文件目录
          • 2.Monster.java
          • 3.SunConfig.java
          • 4.SunHiController.java
        • 3.完成关联
          • 1.文件目录
          • 2.编写SunWebApplicationInitializer的onStartup方法
          • 3.修改SunSpringApplication设置Tomcat的上下文路径
          • 4.启动测试
            • 1.报错
            • 2.引入对应版本的jasper包即可
            • 3.重新启动
            • 4.访问测试,成功返回结果

1.搭建SpringBoot底层机制开发环境

1.创建maven项目

image-20240313083809194

2.使用Git管理项目(可以略过)
1.创建一个github存储库

image-20240313084026951

2.克隆到本地,复制文件夹的内容

image-20240313084151328

3.粘贴到idea项目文件夹,将其作为本地仓库与远程仓库关联

image-20240313084316050

3.pom.xml 引入父工程和场景启动器
  • 其实父工程只是指定了引入依赖的默认版本
  • 真正的依赖是场景启动器来引入的
  <!--导入springboot父工程--><parent><artifactId>spring-boot-starter-parent</artifactId><groupId>org.springframework.boot</groupId><version>2.5.3</version></parent><dependencies><!--配置maven项目场景启动器,自动导入和web相关的包--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
4.编写运行类

image-20240313085051775

package com.sun.springboot;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;/*** @author 孙显圣* @version 1.0*/
@SpringBootApplication
public class MainApp {public static void main(String[] args) {ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);}
}
5.启动运行类,思考:tomcat怎么启动的?

image-20240313085325966

2.@Configuration机制梳理

1.环境搭建
1.文件目录

image-20240313090416238

2.Dog.java
package com.sun.springboot.bean;/*** @author 孙显圣* @version 1.0*/
public class Dog {}
3.Config.java 注入单例Dog对象
package com.sun.springboot.config;import com.sun.springboot.bean.Dog;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @author 孙显圣* @version 1.0*/
@Configuration //作为一个配置类
public class Config {@Bean //将单例bean:Dog注入容器public Dog dog() {return new Dog();}
}
4.MainApp.java测试是否能够获取bean
package com.sun.springboot;import com.sun.media.sound.SoftTuning;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;/*** @author 孙显圣* @version 1.0*/
@SpringBootApplication
public class MainApp {public static void main(String[] args) {ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);Object bean = ioc.getBean("dog");System.out.println(bean);}
}
5.成功获取

image-20240313090607009

2.机制分析
1.简述

image-20240313092732586

2.图解

image-20240313093222725

3.SpringBoot是怎么启动Tomcat的?

1.环境搭建
1.文件目录

image-20240313103409537

2.HiController.java
package com.sun.springboot.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** @author 孙显圣* @version 1.0*/
@RestController //将所有方法的返回结果转换成json字符串并返回
public class HiController {@RequestMapping("/hi")public String hi() {return "hi sun HiController";}
}
3.测试访问

image-20240313103459664

2.源码分析
1.需求分析

image-20240313103642722

2.创建容器过程
1.run方法打断点

image-20240313104716460

2.进入

image-20240313104909516

3.进入

image-20240313105131573

4.进入 SpringApplication

image-20240313105300872

5.继续进入

image-20240313105551189

6.放行到创建容器的那个方法

image-20240313105648420

7.进入

image-20240313105806714

8.继续进入

image-20240313110021023

9.下一步

image-20240313110106122

10.跳出回到createApplicationContext()方法

image-20240313110138825

3.找到createWebServer()
1.打断点

image-20240313110406371

2.放行,并查看目前的容器

image-20240313110632719

3.进入并执行到refresh方法

image-20240313112421819

4.进入

image-20240313112505918

5.再进入

image-20240313112617071

6.进入

image-20240313112737166

7.放行到那个断点

image-20240313112833276

8.进入

image-20240313112906604

9.下一步,找到了createWebServer方法

image-20240313112932587

4.启动Tomcat
1.进入

image-20240313114552291

2.放行到断点并进入getWebServer

image-20240313114639221

3.进入

image-20240313114709010

4.直接跳出

image-20240313114812126

5.放行到下一个断点,然后进入

image-20240313115149244

6.进入,给initialize方法下断点

image-20240313115415751

7.进入,给tomcat.start()下断点

image-20240313115518081

8.直接放行,tomcat启动成功

image-20240313115552819

9.回到afterRefresh方法(一直跳出),此时应用程序上下文已经刷新成功

image-20240313115657471

10.查看目前的容器,完成初始化

image-20240313115904414

4.SpringBoot(实现底层机制)

1.创建Tomcat并启动
1.排除pom.xml中的 spring-boot-starter-tomcat并引入指定版本的Tomcat
    <!--导入springboot父工程--><parent><artifactId>spring-boot-starter-parent</artifactId><groupId>org.springframework.boot</groupId><version>2.5.3</version></parent><dependencies><!--配置maven项目场景启动器,自动导入和web相关的包--><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时,需要排除spring-boot-starter-tomcat,否则会出现GenericServlet Not Found的提示--><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-core</artifactId><version>8.5.75</version></dependency></dependencies>
2.编写SunSpringApplication.java
1.文件目录

image-20240313135110606

2.创建Tomcat对象,关联Spring容器并启动
package com.sun.sunspringboot;import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Tomcat;
import org.springframework.boot.autoconfigure.web.ServerProperties;/*** @author 孙显圣* @version 1.0*/
public class SunSpringApplication {/*** 创建Tomcat对象,关联Spring容器并启动*/public static void run() {try {Tomcat tomcat = new Tomcat();tomcat.setPort(9090);tomcat.start();System.out.println("Tomcat在9090端口监听");tomcat.getServer().await(); //等待} catch (LifecycleException e) {throw new RuntimeException(e);}}
}
3.编写SunMainApp.java,启动Tomcat
package com.sun.sunspringboot;/*** @author 孙显圣* @version 1.0*/
public class SunMainApp {public static void main(String[] args) {SunSpringApplication.run();}
}
4.结果展示

image-20240313135738758

image-20240313135753440

2.创建Spring容器
1.文件目录

image-20240313141342870

2.Monster.java
package com.sun.sunspringboot.bean;/*** @author 孙显圣* @version 1.0*/
public class Monster {}
3.SunConfig.java
package com.sun.sunspringboot.config;import com.sun.sunspringboot.bean.Monster;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;/*** @author 孙显圣* @version 1.0*/
@Configuration //配置类
@ComponentScan("com.sun.sunspringboot") //指定要扫描的包
public class SunConfig {@Beanpublic Monster monster() {return new Monster(); //单例bean注入容器}
}
4.SunHiController.java
package com.sun.sunspringboot.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** @author 孙显圣* @version 1.0*/
@RestController
public class SunHiController {@RequestMapping("/sunhi")public String hi() {return "hi, SunHiController";}
}
3.完成关联
1.文件目录

image-20240313145136167

2.编写SunWebApplicationInitializer的onStartup方法
  • 在Tomcat启动的时候会调用onStartup方法
  • 首先注册配置类,然后将中央控制器放到 servletContext
package com.sun.sunspringboot;import com.sun.sunspringboot.config.SunConfig;
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;/*** 1.创建自己的Spring容器* 2.关联spring容器的配置* 3.完成spring容器配置的bean的创建,依赖注入* 4.完成中央控制器,并让其持有Spring容器* 5.这里的onStartup是Tomcat调用,并把ServletContext对象传入*/
public class SunWebApplicationInitializer implements WebApplicationInitializer {@Overridepublic void onStartup(ServletContext servletContext) throws ServletException {System.out.println("start up");AnnotationConfigWebApplicationContext ac =new AnnotationConfigWebApplicationContext();//完成bean的创建和配置ac.register(SunConfig.class); //在ac中注册配置类ac.refresh();//创建中央控制器DispatcherServlet dispatcherServlet = new DispatcherServlet(ac);//将中央控制器放到servletContextServletRegistration.Dynamic registration = servletContext.addServlet("app", dispatcherServlet);//当tomcat启动时,加载中央控制器registration.setLoadOnStartup(1);//拦截请求,进行分发处理registration.addMapping("/");}
}
3.修改SunSpringApplication设置Tomcat的上下文路径

image-20240313145402807

4.启动测试
1.报错

image-20240313145445745

2.引入对应版本的jasper包即可
        <dependency><groupId>org.apache.tomcat</groupId><artifactId>tomcat-jasper</artifactId><version>8.5.75</version></dependency>
3.重新启动

image-20240313145910622

4.访问测试,成功返回结果

image-20240313150359027

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

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

相关文章

AI壁纸号一周增加上千粉丝,轻松变现的成功案例分享

前言 随着AI绘画技术的发展&#xff0c;传统的互联网副业壁纸号在新的技术加持下迎来了第二春。本文将分享一位壁纸号创作者的成功案例&#xff0c;并为大家提供创作门槛和硬件要求等相关信息。 该项目的创作门槛极低&#xff0c;基本上可以由AI完成内容创作。不过&#xff0…

LM358P/LM358DR/LM358DT/LM358DR2G运算放大器中文资料PDF数据手册引脚图功能

产品概述&#xff1a; LM358B 和 LM2904B 器件是行业标准运算放大器 LM358 和 LM2904 的下一代版本&#xff0c;其中包括两个高压 (36V) 运算放大器。这些器件为成本敏感型应用提供了卓越的价值&#xff0c;其特性包括低偏移&#xff08;300V&#xff0c;典型值&#xff09;、…

C++11新特性【右值引用】

文章目录 1. 什么是左值2. 什么是右值3. 左值引用4. 左值引用使用场景5. 右值引用6. 右值引用使用场景6.1 场景16.2 场景2 7. 完美转发 1. 什么是左值 左值不能根据字面意思来理解&#xff0c;不是说在左边的就是左值&#xff0c;例如&#xff1a; int main() {int a 0;int …

Windows11安装NodeJS18并配置环境变量

从官网下载&#xff0c;或者从百度网盘下载 解压下载的zip包&#xff1a; 重命名为nodejs&#xff1a; 在nodejs中添加cache和global两个目录&#xff1a; 将nodejs和nodejs\global添加到环境变量&#xff1a; 打开终端&#xff0c;输入&#xff1a; node -v接着配置…

高效备考2024年AMC10:吃透2000-2023年1250道真题(限时免费送)

我们今天继续来随机看5道AMC10真题&#xff0c;以及详细解析&#xff0c;这些题目来自1250道完整的官方历年AMC10真题库。通过系统研究和吃透AMC10的历年真题&#xff0c;参加AMC10的竞赛就能拿到好名次。 即使不参加AMC10竞赛&#xff0c;初中和高中数学一定会学得比较轻松、…

(开源项目)OpenHarmony、社区共建Sample合入要求

1.新增Sample功能不能重复于当前已有Sample的功能&#xff1b; 2.新增Sample的工程推荐使用ArkTS语言编写&#xff1b; 3.新增Sample的工程推荐使用Stage模型编写&#xff1b; 4.新增Sample的工程中需要包含UI自动化用例&#xff08;ohosTest工程模块&#xff09;&#xff0…

浅谈船舶岸电系统绝缘监测及故障定位需求及应用

彭姝麟 Acrelpsl 0 项目背景 随着现代船舶发展&#xff0c;船舶电气化程度越来越高&#xff0c;船舶电站的的容量也越来越大&#xff0c;随之而来的是电网的绝缘问题更加复杂化。船舶电力系统一般采用IT系统&#xff0c;即不接地系统。IT系统的优点是发生单相接地时不会出现TN…

2014

1,写出计算Ack(m,n)的递归算法 #include<iostream> using namespace std; int A(int m,int n){if(m0){return n1;}else if(m>0&&n0){return A(m-1,1);}else{return A(m-1,A(m,n-1));} }int main(){int m,n;cout<<"please input two number"&l…

SpringCloud Hystrix 断路器

一、前言 接下来是开展一系列的 SpringCloud 的学习之旅&#xff0c;从传统的模块之间调用&#xff0c;一步步的升级为 SpringCloud 模块之间的调用&#xff0c;此篇文章为第五篇&#xff0c;即介绍 Hystrix 断路器。 二、概述 2.1 分布式系统面临的问题 复杂分布式体系结构中…

了解融云敏感词过滤规则和匹配效果

使用即时通讯&#xff08;IM&#xff09;服务内置了开箱即用的敏感词机制时&#xff0c;可能需要在在开发者后台 配置内置敏感词服务 2 添加敏感词。本文描述了敏感词字符串的设置规则和匹配效果。 简体、繁体智能过滤 设置中文简体敏感词后&#xff0c;对应繁体敏感词也会自…

Scrapy 爬虫框架

网络爬虫框架scrapy &#xff08;配置型爬虫&#xff09; 什么是爬虫框架&#xff1f; 爬虫框架是实现爬虫功能的一个软件结构和功能组件集合爬虫框架是个半成品&#xff0c;帮助用户实现专业网络爬虫 scrapy框架结构("52"结构) spider: 解析downloader返回的响…

BM1684X搭建sophon c++环境

1:首先安装编译好sophon-sail 比特大陆BM1684X开发环境搭建--SOC mode-CSDN博客 2:在将之前配置的soc-sdk拷贝一份到sdk根目录&#xff0c;将交叉编译好的sail中的build_soc拷贝至soc-sdk文件夹内&#xff1b; cp -rf build_soc/sophon-sail/inlcude soc-sdk cp -rf build_soc…