没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
Tomcat 在 Spring Boot 中是如何启动的
前言
我们知道
S
p
r
i
n
g
B
oo
t
给我们带来了一个全新的开发体验,我们可以直接把
w
e
b
程序达成
j
a
r
包,直接启动,这就得益于
S
p
r
i
n
g
B
oo
t
内置了容器,可以直接启动,本文将以
T
o
m
ca
t
为例,来看看
S
p
r
i
n
g
B
oo
t
是如何启动
T
o
m
ca
t
的,同时也将展开学习下
T
o
m
ca
t
的
源码,了解
T
o
m
ca
t
的设计。
从 Main 方法说起
用过SpringBoot的人都知道,首先要写一个main方法来启动
我们直接点击run方法的源码,跟踪下来,发下最终 的run方法是调用ConfigurableApplicationContext方法,源码如下:
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<springbootexceptionreporter> exceptionReporters = new ArrayList<>();
//设置系统属性『java.awt.headless』,为true则启用headless模式�持
configureHeadlessProperty();
//通过*SpringFactoriesLoader*检索*META-INF/spring.factories*,
//找到声明的所有SpringApplicationRunListener的实现类并将其实例化,
//之后逐个调用其started()方法,�播SpringBoot要开始执�了
SpringApplicationRunListeners listeners = getRunListeners(args);
//发布应用开始启动事件
listeners.starting();
try
{
//初始化参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
//创建并配置当前SpringBoot应用将要使用的Environment(包括配置要使用的PropertySource以及Profile),
//并遍历调用所有的SpringApplicationRunListener的environmentPrepared()方法,�播Environment准备完毕。
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
configureIgnoreBeanInfo(environment);
//打印banner
Banner printedBanner = printBanner(environment);
//创建应用上下文
context = createApplicationContext();
//通过*SpringFactoriesLoader*检索*META-INF/spring.factories*,获取并实例化异常分析器
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
//为ApplicationContext加载environment,之后逐个执�ApplicationContextInitializer的initialize()方法来进一步封装ApplicationContext,
//并调用所有的SpringApplicationRunListener的contextPrepared()方法,【EventPublishingRunListener只提供了一个空的contextPrepare
//之后初始化IoC容器,并调用SpringApplicationRunListener的contextLoaded()方法,�播ApplicationContext的IoC加载完成,
//这里就包括通过**@EnableAutoConfiguration**导入的各种�动配置类。
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
//刷新上下文
refreshContext(context);
//再一次刷新上下文,其实是空方法,可能是为了后续扩展。
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
//发布应用已经启动的事件
listeners.started(context);
//遍历所有注册的ApplicationRunner和CommandLineRunner,并执�其run()方法。
//我们可以实现��的ApplicationRunner或者CommandLineRunner,来对SpringBoot的启动过程进�扩展。
callRunners(context,
applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try
{
//应用已经启动完成的监听事件
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return
context;
}
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);
}
其实这个方法我们可以简单的总结下步骤为
1.
配置属性
2.
获取监听器,发布应用开始启动事件
3.
初始化输入参数
4.
配置环境,输出banner
5.
创建上下文
6.
预处理上下文
7.
刷新上下文
8.
再刷新上下文
9.
发布应用已经启动事件
10.
发布应用启动完成事件
其实上面这段代码,如果只要分析
t
o
m
ca
t
内容的话,只需要关注两个内容即可,上下文是如何创建的,上下文是如何刷新的,分
别对应的方法就是
c
r
e
a
t
e
A
pp
l
i
ca
t
i
o
n
C
o
n
t
e
x
t
()
和
r
e
f
r
e
s
h
C
o
n
t
e
x
t
(
c
o
n
t
e
x
t
)
,接下来我们来看看这两个方法做了什么。
欢迎关注微信公众号:Java后端
这里就是根据我们的webApplicationType 来判断创建哪种类型的Servlet,代码中分别对应着Web类型(SERVLET),响应式Web类型
(REACTIVE),非Web类型(default),我们建立的是Web类型,所以肯定实例化
D
E
F
A
U
L
T
_
S
E
R
V
L
E
T
_
W
E
B
_
C
O
N
T
EX
T
_
C
L
A
SS
指定的类,也就是
A
nn
o
t
a
t
i
o
n
C
o
n
f
i
g
S
e
r
v
l
e
t
W
e
b
S
e
r
v
e
r
A
pp
l
i
ca
t
i
o
n
C
o
n
t
e
x
t
类
,我们来用图来说明下这个类的关系
剩余11页未读,继续阅读
资源评论
小小哭包
- 粉丝: 1902
- 资源: 3901
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功