实现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 {//创建TomcatTomcat 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 {@Beanpublic 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 {@Overridepublic 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 {//创建TomcatTomcat 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>
通过浏览器发送请求得到