😀前言
本篇博文是关于SpringBoot 底层机制分析实现,希望能够帮助你更好的了解SpringBoot 😊
🏠个人主页:晨犀主页
🧑个人简介:大家好,我是晨犀,希望我的文章可以帮助到大家,您的满意是我的动力😉😉
💕欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,感谢大家的观看🥰
如果文章有什么需要改进的地方还请大佬不吝赐教 先在此感谢啦😊
文章目录
- 分析SpringBoot 底层机制【Tomcat 启动分析+Spring 容器初始化+Tomcat 如何关联Spring 容器】
- 实现任务阶段1- 创建Tomcat, 并启动
- ● 代码实现
- 完成测试
- 运行效果
- 实现任务阶段2- 创建Spring 容器
- ● 代码实现
- 实现任务阶段3- 将Tomcat 和Spring 容器关联, 并启动Spring 容器
- ● 代码实现
- 完成测试
- 注意事项和细节
- 😄总结
分析SpringBoot 底层机制【Tomcat 启动分析+Spring 容器初始化+Tomcat 如何关联Spring 容器】
实现任务阶段1- 创建Tomcat, 并启动
说明: 创建Tomcat, 并启动
● 代码实现
1.修改nlc-springboot\pom.xml
<?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.nlc</groupId>
<artifactId>nlc-springboot</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 导入springboot 父工程,规定的写法
解读:
1. springboot 我们指定2.5.3
-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.3</version>
</parent>
<!-- 导入web 项目场景启动器,会自动导入和web 开发相关依赖,非常方便-->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--用我们指定tomcat 版本来完, 可以到mvn 去获取依赖坐标.
解读:
1. 使用指定的tomcat 才会验证,效果高版本的tomcat默认不会真正监听
2. 使用了指定tomcat , 需要在spring-boot-starter-web 排除内嵌的 starter-tomcat
3. 否则会出现包冲突, 提示GenericServlet Not Found 类似错误
-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>8.5.75</version>
</dependency>
</dependencies>
</project>
2 、创建nlc-springboot\src\main\java\com\nlc\nlcspringboot\NlcSpringApplication.java
public class NlcSpringApplication {
//这里我们会创建tomcat对象,并关联Spring容器, 并启动
public static void run() {
try {
//创建Tomcat对象 NlcTomcat
Tomcat tomcat = new Tomcat();
//1. 让tomcat可以将请求转发到spring web容器,因此需要进行关联
//2. "/nlcboot" 就是我们的项目的 application context , 就是我们原来配置tomcat时,指定的application context
//3. "D:\\nlc_springboot\\nlc-springboot" 指定项目的目录
tomcat.addWebapp("/nlcboot","D:\\nlc_springboot\\nlc-springboot");
//设置9090
tomcat.setPort(9090);
//启动
tomcat.start();
//等待请求接入
System.out.println("======9090====等待请求=====");
tomcat.getServer().await();
} catch (Exception e) {
e.printStackTrace();
}
}
}
3、创建nlc-springboot\src\main\java\com\nlc\nlcspringboot\NlcMainApp.java
public class NlcMainApp {
public static void main(String[] args) {
//启动NlcSpringBoot项目/程序
NlcSpringApplication.run();
}
}
完成测试
运行效果
浏览器请求, http://localhost:9090/ , 这时没有返回信息
实现任务阶段2- 创建Spring 容器
说明: 创建Spring 容器
● 代码实现
1 、创建nlc-springboot\src\main\java\com\nlc\nlcspringboot\bean\Monster.java , 做一个测试Bean
public class Monster {
}
2 、创建nlc-springboot\src\main\java\com\nlc\nlcspringboot\controlller\HiController.java, 作为Controller
@RestController
public class NlcHiController {
@RequestMapping("/hi")
public String hi() {
System.out.println("hi i am HiController");
return "hi i am HiController";
}
}
3 、创建nlc-springboot\src\main\java\com\nlc\nlcspringboot\config\NlcConfig.java , 作为Spring 的配置文件.
@Configuration
@ComponentScan("com.nlc.nlcspringboot")
public class NlcConfig {
/**
* 1. 通过@Bean 的方式, 将new 出来的Bean 对象, 放入到Spring 容器
* 2. 该bean 在Spring 容器的name 就是方法名
* 3. 通过方法名, 可以得到new Monster()
*/
@Bean
public Monster monster() {
return new Monster();
}
}
4 、创建nlc-springboot\src\main\java\com\nlc\nlcspringboot\NlcWebApplicationInitializer.java , 作为Spring 的容器.
/**
* 解读
* 1. 创建我们的Spring 容器
* 2. 加载/关联Spring容器的配置-按照注解的方式
* 3. 完成Spring容器配置的bean的创建, 依赖注入
* 4. 创建前端控制器 DispatcherServlet , 并让其持有Spring容器
* 5. 当DispatcherServlet 持有容器, 就可以进行分发映射, 回忆我们实现SpringMVC底层机制
* 6. 这里onStartup 是Tomcat调用, 并把ServletContext 对象传入
*/
public class NlcWebApplicationInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
System.out.println("startup ....");
//加载Spring web application configuration => 容器
//自己 写过 NlcSpringApplicationContext
AnnotationConfigWebApplicationContext ac =
new AnnotationConfigWebApplicationContext();
//在ac中注册 NlcConfig.class 配置类
ac.register(NlcConfig.class);
ac.refresh();//刷新上下文,完成bean的创建和配置
//1. 创建注册非常重要的前端控制器 DispatcherServlet
//2. 让DispatcherServlet 持有容器
//3. 这样就可以进行映射分发, 回忆一下SpringMvc机制[自己实现过]
//NlcDispatcherServlet
DispatcherServlet dispatcherServlet = new DispatcherServlet(ac);
//返回了ServletRegistration.Dynamic对象
ServletRegistration.Dynamic registration =
servletContext.addServlet("app", dispatcherServlet);
//当tomcat启动时,加载 dispatcherServlet
registration.setLoadOnStartup(1);
//拦截请求,并进行分发处理
//这里提示/ 和/*的配置,会匹配所有的请求,
//当Servlet 配置了"/", 会覆盖tomcat 的DefaultServlet, 当其他的utl-pattern 都匹配不上时, 都会走这个Servlet, 这样可以拦截到其它静态资源
//这个默认的servlet 是处理静态资源的,一旦拦截,静态资源不能处理
//当Servelt 配置了"/*", 表示可以匹配任意访问路径
registration.addMapping("/");
}
}
实现任务阶段3- 将Tomcat 和Spring 容器关联, 并启动Spring 容器
说明: 将Tomcat 和Spring 容器关联, 并启动Spring 容器
● 代码实现
- 修改nlc-springboot\src\main\java\com\nlc\nlcspringboot\NlcSpringApplication.java
public class NlcSpringApplication {
//这里我们会创建tomcat对象,并关联Spring容器, 并启动
public static void run() {
try {
//创建Tomcat对象 NlcTomcat
Tomcat tomcat = new Tomcat();
//1. 让tomcat可以将请求转发到spring web容器,因此需要进行关联
//2. "/nlcboot" 就是我们的项目的 application context , 就是我们原来配置tomcat时,指定的application context
//3. "D:\\nlc_springboot\\nlc-springboot" 指定项目的目录
tomcat.addWebapp("/nlcboot","D:\\nlc_springboot\\nlc-springboot");
//设置9090
tomcat.setPort(9090);
//启动
tomcat.start();
//等待请求接入
System.out.println("======9090====等待请求=====");
tomcat.getServer().await();
} catch (Exception e) {
e.printStackTrace();
}
}
}
- debug 一下, 看看是否进行Spring 容器的初始化工作, 可以看到ac.refresh() 会将NlcConfig.class 中配置Bean 实例化装入到容器中…
里面有很多,可以自己看看
完成测试
1、启动项目, 运行NlcMainApp
public class NlcMainApp {
public static void main(String[] args) {
//启动NlcSpringBoot项目/程序
NlcSpringApplication.run();
}
}
2、运行的效果
注意事项和细节
1、如果启动包异常, 如下:
严重: Servlet [jsp] in web application [/nlcboot] threw load() exception
java.lang.ClassNotFoundException: org.apache.jasper.servlet.JspServlet
2 、解决方案, 引入对应版本的jasper 包即可, 修改nlc-springboot\pom.xml
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper</artifactId>
<version>8.5.75</version>
</dependency>
😄总结
- 如果启动包异常出现上述异常, 引入对应版本的jasper 包就可以解决。
- 前面配置的application context可以根据自己的需求修改。
- 指定项目的目录要根据自己的项目情况进行修改,否则会出现FileNotFoundException(系统找不到指定的文件)或NoSuchFileException(没有此类文件)。
😁热门专栏推荐
SpringBoot篇
SpringBoot 底层机制分析[上]
SpringBoot容器–注解的使用
SpringBoot 自动配置–常用配置
SpringBoot 依赖管理和自动配置—带你了解什么是版本仲裁
Spring Boot介绍–快速入门–约定优于配置
文章到这里就结束了,如果有什么疑问的地方请指出,诸大佬们一起来评论区一起讨论😁
希望能和诸大佬们一起努力,今后我们一起观看感谢您的阅读🍻
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞