前言
Spring Boot 是一个开源的框架,用于简化 Spring 应用程序的开发和部署。它建立在 Spring Framework 的基础上,内置了web服务器——tomcat和jetty,使得 Spring 应用的构建变得更加快速、简单和可维护。
本文通过实现一个SpringBoot,学习SpringBoot是如何进行工作的。
创建两个模块
- springboot:模拟实现springboot框架
- user:测试调用实现的springboot架构的用户业务系统
引入依赖包
- SpringBoot基于Spring架构,需要在springboot模块中依赖Spring
- SpringBoot也支持Spring MVC功能,依赖Spring MVC和Tomcat等
在SpringBoot模块中要添加以下依赖。
<?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"> <parent> <artifactId>simulate-springboot</artifactId> <groupId>org.example</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>springboot</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.18</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.3.18</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.18</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> <version>9.0.60</version> </dependency> </dependencies> </project>
对于user模块,添加springboot模块即可
<?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"> <parent> <artifactId>simulate-springboot</artifactId> <groupId>org.example</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>user</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.example</groupId> <artifactId>springboot</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </project>
实现SpringBoot简单功能
以下代码若无特别说明则均在springboot模块中,具体位置请查看项目文件结构。
@BerSpringBootApplication注解
package com.ber.springboot; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /** * @Author 鳄鱼儿 * @Description TODO * @date 2023/8/19 14:05 * @Version 1.0 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Configuration
@ComponentScan
public @interface BerSpringBootApplication {
}
BerSpringApplication启动类
package com.ber.springboot; import org.apache.catalina.*;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.startup.Tomcat;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet; /** * @Author 鳄鱼儿 * @Description TODO * @date 2023/8/19 14:08 * @Version 1.0 */
public class BerSpringApplication { public static void run(Class clazz) { // 1. 创建Spring 容器 AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext(); applicationContext.register(clazz); applicationContext.refresh(); // 2. 创建并启动Tomcat startTomcat(applicationContext); } private static void startTomcat(WebApplicationContext applicationContext) { // 2.1 创建tomcat对象 Tomcat tomcat = new Tomcat(); Server server = tomcat.getServer(); Service service = server.findService("Tomcat"); Connector connector = new Connector(); // 设置默认tomcat启动端口 connector.setPort(8023); Engine engine = new StandardEngine(); engine.setDefaultHost("localhost"); Host host = new StandardHost(); host.setName("localhost"); String contextPath = ""; Context context = new StandardContext(); context.setPath(contextPath); context.addLifecycleListener(new Tomcat.FixContextListener()); host.addChild(context); engine.addChild(host); service.setContainer(engine); service.addConnector(connector); // 2.2 创建DispatcherServlet对象,并与Spring容器绑定,并将DispatcherServlet对象添加至Tomcat中 tomcat.addServlet(contextPath, "dispatcher", new DispatcherServlet(applicationContext)); context.addServletMappingDecoded("/*", "dispatcher"); // 2.3 启动tomcat try { tomcat.start(); } catch (LifecycleException e) { e.printStackTrace(); } }
}
run方法实现
user模块中Controller方法被浏览器请求时,就需要run方法去启动一个tomcat,并需要通过一个Servlet接收所有的请求,并将请求分发给相应的Controller进行处理。
在Spring MVC中,DispatcherServlet就起到这个前端控制器的作用。DispatcherServlet需要绑定一个Spring容器,当DispatcherServlet接收到请求后,就可以从绑定的Spring容器中找到所匹配的Controller,并执行对应的方法。
因此,在run方法中实现了:
- 创建一个Spring容器
- 创建并启动Tomcat
- 创建tomcat对象
- 创建DispatcherServlet对象,并与Spring容器绑定,并将DispatcherServlet对象添加至Tomcat中
- 启动Tomcat
创建spring容器
创建了一个AnnotationConfigApplicationContext容器,并通过传入的clazz作为容器的配置类。
那么,是如何将clazz作为配置类的呢?
在user模块中,UserApplication启动类是这样的。
package com.ber.user; import com.ber.springboot.BerSpringApplication;
import com.ber.springboot.BerSpringBootApplication; /** * @Author 鳄鱼儿 * @Description TODO * @date 2023/8/19 14:10 * @Version 1.0 */
@BerSpringBootApplication
public class UserApplication { public static void main(String[] args) { BerSpringApplication.run(UserApplication.class); }
}
将UserApplication.class传入run方法,UserApplication类就是AnnotationConfigWebApplicationContext容器的配置类。
配置过程为:
在Spring容器AnnotationConfigWebApplicationContext创建好后,该容器内部就拥有了user模块下启动类所在包路径下的Bean。
创建并启动Tomcat
在startTomcat()方法中,创建了tomcat对象,并对tomcat进行配置,如默认端口8023,创建和配置 Tomcat 引擎和主机等。然后再创建DispatcherServlet对象,并与Spring容器绑定,并将DispatcherServlet对象添加至Tomcat中。
当运行user模块的UserApplication启动类时,调用BerSpringApplication类中的run方法,所以在run方法中调用startTomcat()方法。
到此,就可以试着运行BerSpringBoot了,可以看到已经成功启动tomcat,并成功访问到了
http://localhost:8023/test