springboot源码解析-管中窥豹系列之项目类型(二)
一、前言
- Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去。
- 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot源码管中窥豹系列。

二、项目类型
这一节我们先讨论一下springboot项目的怎么自动加载applicationcontext实现类的。
- 以前的spring的项目,都是xml加载bean,常用的都是XmlWebApplicationContext实现类
- 后来出现注解的形式,基本用AnnotationConfigWebApplicationContext实现类
- 后来又出现响应式编程reactive
那springboot用的是哪一种呢?
三、源码解读
先说结论:关于类型的选择,springboot是根据class来判断的。
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
...
this.webApplicationType = WebApplicationType.deduceFromClasspath();
...
}
- 我们从SpringApplication的构造函数开始看起
- 构造函数里面有段代码:是确定类型的
我们先看类型:
private static final String[] SERVLET_INDICATOR_CLASSES = { "javax.servlet.Servlet",
"org.springframework.web.context.ConfigurableWebApplicationContext" };
private static final String WEBMVC_INDICATOR_CLASS = "org.springframework.web.servlet.DispatcherServlet";
private static final String WEBFLUX_INDICATOR_CLASS = "org.springframework.web.reactive.DispatcherHandler";
private static final String JERSEY_INDICATOR_CLASS = "org.glassfish.jersey.servlet.ServletContainer";
static WebApplicationType deduceFromClasspath() {
if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
return WebApplicationType.REACTIVE;
}
for (String className : SERVLET_INDICATOR_CLASSES) {
if (!ClassUtils.isPresent(className, null)) {
return WebApplicationType.NONE;
}
}
return WebApplicationType.SERVLET;
}
- 第一段if,如果存在reactive包的DispatcherServlet,同时不存在jersey和mvc的DispatcherHandler,就是REACTIVE
- 第二段循环,不存在Servlet或者ConfigurableWebApplicationContext,就是none
- 剩下的就是我们熟悉的SERVLET
类型确定之后,我们看SpringApplication的run方法:
public ConfigurableApplicationContext run(String... args) {
...
try {
...
context = createApplicationContext();
...
} catch (Throwable ex) {
...
}
...
return context;
}
ApplicationContext实现类就是在createApplicationContext()里面确定的
public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context."
+ "annotation.AnnotationConfigApplicationContext";
public static final String DEFAULT_SERVLET_WEB_CONTEXT_CLASS = "org.springframework.boot."
+ "web.servlet.context.AnnotationConfigServletWebServerApplicationContext";
public static final String DEFAULT_REACTIVE_WEB_CONTEXT_CLASS = "org.springframework."
+ "boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext";
protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {
switch (this.webApplicationType) {
case SERVLET:
contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
break;
case REACTIVE:
contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
break;
default:
contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
}
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex);
}
}
return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}
根据类型加载不同的class:
- 如果是SERVLET:AnnotationConfigServletWebServerApplicationContext
- 如果是REACTIVE:
AnnotationConfigReactiveWebServerApplicationContext - default:AnnotationConfigApplicationContext
至此,一目了然了,想要不同的项目类型,添加对应的jar包,springboot自动帮你选择对应的ApplicationContext实现类
如果是普通的web项目:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
如果是reactive项目:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
如果是非web项目:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
欢迎关注公众号:丰极,更多技术学习分享。
springboot源码解析-管中窥豹系列之项目类型(二)的更多相关文章
- springboot源码解析-管中窥豹系列之web服务器(七)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列之BeanDefine如何加载(十三)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列之BeanPostProcessor(十二)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列之bean如何生成?(十四)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列之BeanDefinition(八)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列之自动装配(九)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列之EnableXXX(十)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列之BeanFactoryPostProcessor(十一)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
随机推荐
- 乌云wooyun网站硬盘复活
AWD比赛防止没有网络,在移动硬盘里面准备一个乌云漏洞库. 之前也想过弄一个乌云的镜像网站,无奈学生机性能太低下了,部署到公网上服务器存储空间都不够,只能部署在本地硬盘了. 乌云镜像的开源地址:htt ...
- VirtualBox安装Centos出现E_FAIL (0x80004005)的解决方法
问题描述:UUID已经存在 Cannot register the hard disk 'F:\hadoop\VirtualBox-centos\centos6.4\centos6.4.vdi' {0 ...
- AGC039D 题解
题目描述 给定在笛卡尔坐标系的单位圆上的\(N\)个点(圆心为\((0, 0)\)).第\(i\)个点的坐标为\((cos(\frac{2 \pi T_i}{L}), sin(\frac{2 \pi ...
- ajax与浏览器请求的差异对比.png
- uniapp保存图片到本地(APP和微信小程序端)
uniapp实现app端和微信小程序端图片保存到本地,其它平台未测过,原理类似. 微信小程序端主要是权限需要使用button的开放能力来反复调起,代码如下: 首先是条件编译两个平台的按钮组件: < ...
- uni-app快速入门教程
1.什么是uni-app? uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS.Android.H5.以及各种小程序(微信/支付宝/百度/头条/QQ/ ...
- 小米k30 pro刷国际版rom
时间:2020.8.20 最新的是miui12但是普遍反映耗电量巨大,所以还是刷miui11了. 知乎上有个教程:https://zhuanlan.zhihu.com/p/86160027 但是是针对 ...
- PDF格式分析
系列文章是csdn作者'秋风之刀'写的,我只是把目录列出来而已,感谢作者辛苦付出. PDF格式分析(一)简介 PDF格式分析(二)语法之对象 PDF格式分析(三)语法之Filter PDF格式分析(四 ...
- md5 的基本使用
import hashlib def make_password(password): md5=hashlib.md5() # 实例化 md5.update(password.encode(encod ...
- AWT08-绘图
1.组件绘图原理 Java GUI能展示出不同对话框.窗口等等组件外观的本质其实就是绘图. 在AWT中,真正提供绘图功能的是Graphics对象,在Component中提供了三个方法来完成组件图形的绘 ...