文章目录
- 创建自己的Springboot
- 创建项目
- 注册、启动Spring容器
- 启动tomcat
- 引用测试
创建自己的Springboot
首先明确本文章想要达到的目的,就是引入我们自己写的Springboot项目的依赖,无需配置,就可以达到处理普通请求的效果.
这里有一个非常简单的Springboot项目,项目里面就只有一个controller类
pom中就只引入了一个Springboot的依赖
当我们启动项目后,访问http://localhost:8080/test就可以得到返回结果.
那么我们想做的就是把这个依赖换成我们自己写的Springboot项目,也能达到同样的效果.
那Springboot帮我们做了哪些事情,就可以达到这样的效果呢? 这里其实主要有两件事情.
- 注册、启动Spring容器
- 启动tomcat
所以接下来,我们就会尝试去做这个东西,手写我们自己的Springboot.
创建项目
这里首先创建了一个Spring项目,因为Springboot肯定是依赖于Spring的.项目总体结构如下:
启动类BlingSpringApplication,将来使用方就是调用这个run方法去启动我们自己的Springboot的,只不过现在是空的.
这里也模仿Springboot去定义了一个注解,将来便于调用方进行标识使用.
pom如下:
<?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>cn.com.bling</groupId>
<artifactId>springboot</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- 引入一些基础的spring依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!-- servlet依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<!-- web容器依赖-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>9.0.37</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.eclipse.jetty</groupId>-->
<!-- <artifactId>jetty-server</artifactId>-->
<!-- <version>9.4.51.v20230217</version>-->
<!-- </dependency>-->
</dependencies>
</project>
注册、启动Spring容器
建好了我们自己的Springboot项目,接下来就需要注册、启动Spring容器了.
其实代码很简单,只有三行.就写在我们的run方法里面.
这里需要注意一下,我们注册,启动Spring容器,需要传入一个类.这个类一般会是启动类.那为什么要传入一个类呢?
-
其实最主要的就是为了能够解析到一个路径,我们知道springboot会默认扫描一个包路径,将这个包路径下面所有需要的bean都注册到spring容器中
那这个路径是怎么确定的呢? 其实就是这个传入类所在的包路径.会解析这个传入类上的所有注解(包括注解上的注解),然后如果有ComponentScan注解的话,就会进行扫描注入.
public static void run(Class clazz) {
//new 一个Spring容器对象
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
/**
* 对spring进行注册,这里为什么要传入一个类?
* 其实最主要的就是为了能够解析到一个路径,我们知道springboot会默认扫描一个包路径,将这个包路径下面所有需要的bean都注册到spring容器中
* 那这个路径是怎么确定的呢? 其实就是这个传入类所在的包路径.
* 会解析这个传入类上的所有注解(包括注解里的注解),然后如果有ComponentScan注解的话,就会进行处理
*/
applicationContext.register(clazz);
//真正扫描路径,初始化bean的步骤
applicationContext.refresh();
}
启动tomcat
有了Spring容器,就可以启动tomcat了.
为什么要先初始化Spring容器呢?
因为tomcat作为一个servlet容器, 需要一个servlet.,在SpringMVC中,这个servlet是由DispatcherServlet来实现的,由它进行请求的分发,处理.
而DispatcherServlet是需要Spring容器的,因为tomcat启动后会将所有的请求交给DispatcherServlet去进行处理,DispatcherServlet拿到请求后会根据请求路径去spring容器中找到对应的bean,然后执行对应的方法,然后将结果进行返回.
public class BlingSpringApplication {
public static void run(Class clazz) {
//注册,启动Spring容器
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
/**
* 对spring进行注册,这里为什么要传入一个类?
* 其实最主要的就是为了能够解析到一个路径,我们知道springboot会默认扫描一个包路径,将这个包路径下面所有需要的bean都注册到spring容器中
* 那这个路径是怎么确定的呢? 其实就是这个传入类所在的包路径.
* 会解析这个传入类上的所有注解(包括注解里的注解),然后如果有CompantScan注解的话,就会进行处理
*/
applicationContext.register(clazz);
//真正扫描路径,初始化bean的步骤
applicationContext.refresh();
//启动tomcat
startTomcat(applicationContext);
}
/**
* 启动tomcat
* @param applicationContext
*/
private static void startTomcat(AnnotationConfigWebApplicationContext applicationContext) {
Tomcat tomcat = new Tomcat();
Server server = tomcat.getServer();
Service service = server.findService("Tomcat");
//创建链接,绑定端口
Connector connector = new Connector();
connector.setPort(8080);
StandardEngine standardEngine = new StandardEngine();
standardEngine.setDefaultHost("localhost");
StandardHost host = new StandardHost();
host.setName("localhost");
String contextPath = "";
StandardContext context = new StandardContext();
context.setPath(contextPath);
context.addLifecycleListener(new Tomcat.FixContextListener());
host.addChild(context);
standardEngine.addChild(host);
service.setContainer(standardEngine);
service.addConnector(connector);
/**
* 最主要的一步,需要用到DispatcherServlet,这个是SpringMVC里面的,帮我们进行映射
* 那DispatcherServlet接收到请求怎么处理的呢?
* DispatcherServlet需要一个applicationContext,也就是spring上下文
* tomcat启动后会将所有的请求交给DispatcherServlet去进行处理,DispatcherServlet拿到请求后会根据请求路径去spring上下文中
* 找到对应的bean,然后执行对应的方法,然后将结果进行返回
*
*
*/
tomcat.addServlet(context,"dispatcher",new DispatcherServlet(applicationContext));
context.addServletMappingDecoded("/*","dispatcher");
try {
tomcat.start();
} catch (LifecycleException e) {
e.printStackTrace();
}
}
}
引用测试
现在我们就可以将自己的Springboot打包,发布到本地仓库,进行使用了.
- 替换成我们写的maven依赖
2. 替换成我们自己的注解和启动类.
其他保持不变,启动项目,看是否能达到我们想要的结果.
项目正常启动之后,进行访问. 发现确实可以正常访问.
至此,我们第一步就完成了,当然,目前是一个非常简单的小功能,还非常的不完善,比如说现在不想用tomcat了,想使用jetty,在Springboot中直接切换依赖就可以了,其他都不用动,就可以启动jetty了,那它又是怎样做到的呢?
这个将在后续的文章中不断揭秘.
今天的分享就到这里了,有问题可以在评论区留言,均会及时回复呀.
我是bling,未来不会太差,只要我们不要太懒就行, 咱们下期见.