您现在的位置是:首页 >技术杂谈 >分析SpringBoot 底层机制【Tomcat 启动分析+Spring 容器初始化+Tomcat 如何关联Spring 容器之手动实现网站首页技术杂谈
分析SpringBoot 底层机制【Tomcat 启动分析+Spring 容器初始化+Tomcat 如何关联Spring 容器之手动实现
简介分析SpringBoot 底层机制【Tomcat 启动分析+Spring 容器初始化+Tomcat 如何关联Spring 容器之手动实现
分析SpringBoot 底层机制【Tomcat 启动分析+Spring 容器初始化+Tomcat 如何关联Spring 容器之手动实现
目录
分析SpringBoot 底层机制【Tomcat 启动分析+Spring 容器初始化+Tomcat 如何关联Spring 容器之手动实现
2、浏览器请求, http://localhost:9090/ , 这时没有返回信息
创建HiController.java, 作为Controller
创建WyxConfig.java , 作为Spring 的配置文件.
创建WyxWebApplicationInitializer.java , 作为Spring 的Initializer: 初始化器
实现任务阶段3- 将Tomcat 和Spring 容器关联, 并启动Spring 容器
实现任务阶段1- 创建Tomcat, 并启动
说明:
创建Tomcat, 并启动
分析+代码实现
修改pom.xml
<!-- 导入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>
创建WyxSpringApplication.java
public class WyxSpringApplication {
public static void run() {
try {
Tomcat tomcat = new Tomcat();
tomcat.setPort(9090);
//启动Tomcat
tomcat.start();
//等待请求接入
System.out.println("=====9090====等待请求");
tomcat.getServer().await();
} catch (Exception e) {
e.printStackTrace();
}
}
}
创建WyxMainApp
public class WyxMainApp {
public static void main(String[] args) {
//启动HspSpringBoot项目/程序
WyxSpringApplication.run();
}
}
完成测试
1、运行效果
2、浏览器请求, http://localhost:9090/ , 这时没有返回信息
实现任务阶段2- 创建Spring 容器
代码实现
创建Monster.java , 做一个测试Bean
public class Monster {
}
创建HiController.java, 作为Controller
@RestController
public class WyxHiController {
@RequestMapping("/wyxhi")
public String hi() {
return "hi,wyx WyxHiController";
}
}
创建WyxConfig.java , 作为Spring 的配置文件.
/**
* WyxConfig:配置类-作为Spring的配置文件
* 这里有一个问题,容器怎么知道要扫描哪些包? =>一会代码会体现
*
* 在配置类可以指定要扫描包: @ComponentScan("com.wyxedu.wyxspringboot")
*/
@Configuration
@ComponentScan("com.wyxedu.wyxspringboot")
public class WyxConfig {
//注入Bean - monster 对象到Spring容器.
@Bean
public Monster monster() {
return new Monster();
}
}
创建WyxWebApplicationInitializer.java , 作为Spring 的Initializer: 初始化器
/**
* Initializer: 初始化器
*/
/**
* 解读
* 1. 创建我们的Spring 容器
* 2. 加载/关联Spring容器的配置-按照注解的方式
* 3. 完成Spring容器配置的bean的创建, 依赖注入
* 4. 创建前端控制器 DispatcherServlet , 并让其持有Spring容器
* 5. 当DispatcherServlet 持有容器, 就可以进行分发映射, 请小伙伴回忆我们实现SpringMVC底层机制
* 6. 这里onStartup 是Tomcat调用, 并把ServletContext 对象传入
*/
public class WyxWebApplicationInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
System.out.println("startup ....");
//加载Spring web application configuration => 容器
//自己 写过 WyxSpringApplicationContext
AnnotationConfigWebApplicationContext ac =
new AnnotationConfigWebApplicationContext();
//在ac中注册 WyxConfig.class 配置类
ac.register(WyxConfig.class);
ac.refresh();//完成bean的创建和配置
//1. 创建注册非常重要的前端控制器 DispatcherServlet
//2. 让DispatcherServlet 持有容器
//3. 这样就可以进行映射分发, 回忆一下SpringMvc机制[自己实现过]
//HspDispatcherServlet
DispatcherServlet dispatcherServlet = new DispatcherServlet(ac);
//返回了ServletRegistration.Dynamic对象
ServletRegistration.Dynamic registration =
servletContext.addServlet("app", dispatcherServlet);
//当tomcat启动时,加载 dispatcherServlet
registration.setLoadOnStartup(1);
//拦截请求,并进行分发处理
//这里在提示 / 和 /* => 在 java web专题的web工程路径博客 不知道的朋友可以去看看
registration.addMapping("/");
}
}
实现任务阶段3- 将Tomcat 和Spring 容器关联, 并启动Spring 容器
代码实现
创建WyxSpringApplication.java
public class WyxSpringApplication {
//这里我们会创建tomcat对象,并关联Spring容器, 并启动
public static void run() {
try {
//创建Tomcat对象 HspTomcat
Tomcat tomcat = new Tomcat();
//1. 让tomcat可以将请求转发到spring web容器,因此需要进行关联
//2. "/wyxboot" 就是我们的项目的 application context , 就是我们原来配置tomcat时,指定的application context
//3. "C:UserswangDesktopwyx-springboot" 指定项目的目录
tomcat.addWebapp("/wyxboot","C:\Users\wang\Desktop\wyx-springboot");
//设置9090
tomcat.setPort(9090);
//启动
tomcat.start();
//等待请求接入
System.out.println("======9090====等待请求=====");
tomcat.getServer().await();
} catch (Exception e) {
e.printStackTrace();
}
}
}
2. debug 一下
看看是否进行Spring 容器的初始化工作, 可以看到ac.refresh() 会将WyxConfig.class 中配置Bean 实例化装入到容器中.
完成测试
启动项目, 运行WyxMainApp
运行的效果
注意事项和细节
1、如果启动包异常, 如下:
严重: Servlet [jsp] in web application [/hspboot] threw load() exception
java.lang.ClassNotFoundException: org.apache.jasper.servlet.JspServlet
解决方案, 引入对应版本的jasper 包即可, 修改pom.xml
<!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-jasper -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper</artifactId>
<version>8.5.75</version>
</dependency>
到这里就完成了感谢大家的阅读
因为我之前的博客有手写Tomato Spring SpringMVC MyBits 机制所以这里就手写了Spring-boot这么去启动tomato的代码过程和他的原理。
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。