SpringBoot内嵌tomcat(4)【Tomcat各组件启动时机】源码简析
org.springframework.boot.web.embedded.tomcat.TomcatWebServer
void TomcatWebServer.start()
执行逻辑中: 重点关注 performDeferredLoadOnStartup()方法
上述源码分析可知: Host 下一级是Context, 实例是
TomcatEmbeddedContext:
遍历Context的children(
Wrapper集合)
如果loadOnStartup >=0 则 执行load()方法:
void TomcatWebServer.initialize()
在TomcatWebServer的构造函数中调用 initialize() 方法初始化。最重要的处理逻辑是 Tomcat.start() 来启动服务
而在Tomcat.start() 的代码中实际上是 Server.start()。
org.apache.catalina.core.StandardServer
void StandardServer.start()方法
StandardServer 的超类org.apache.catalina.util.LifecycleBase 提供了 用 synchronized 修饰的 start()方法:
由实例对象重写 initInternal() , startInternal() 。
start()方法只有LifecycleState.NEW才执行init(); init()方法中先设置LifecycleState.INITIALIZING 再执行initInternal();
各层级对象都继承了org.apache.catalina.util.LifecycleBase, 所以基本上处理逻辑大致如下图:
至此大部分的组件都已经启动
void StandardServer.initInternal()方法
不限于:
- 创建公用的线程池ScheduledThreadPoolExecutor (因双向关联关系,一直向下层传递)
这里的线程名称前缀是:"Catalina-utility-" - 触发下一层及的初始化: Service.init()
void StandardServer.startInternal()方法
设置LifecycleState状态为STARTING;
触发调用Service.start() ;
公用线程池调度: 每分钟1次触发LifecycleListener处理LifecycleEvent
void org.apache.catalina.core.StandardContext.startInternal()方法
按 listener > filter > servlet 的顺序来判定执行:(证明了前文介绍的加载顺序和加载时机)
// Configure and call application event listenersif (ok) {
if (!listenerStart()) {
log.error(sm.getString("standardContext.listenerFail"));
ok = false;
}
}
... ...
// Configure and call application filters
if (ok) {
if (!filterStart()) {
log.error(sm.getString("standardContext.filterFail"));
ok = false;
}
}
// Load and initialize all "load on startup" servlets
if (ok) {
if (!loadOnStartup(findChildren())){
log.error(sm.getString("standardContext.servletFail"));
ok = false;
}
}
boolean StandardContext.listenerStart()方法
- 通过指定的applicationListener反射创建listener实例
- 将listener分两类eventListeners | lifecycleListeners, 且缓存在StandardContext对象中 (证明了前文介绍listener分类, 单例)
- 最终调用listener.contextInitialized(ServletContextEvent) 初始化容器
boolean StandardContext.filterStart()方法
每个org.apache.tomcat.util.descriptor.web.FilterDef对应的org.apache.catalina.core.ApplicationFilterConfig实例
在初始化ApplicationFilterConfig时,将实例化对应的javax.servlet.Filter。单例!
boolean StandardContext.loadOnStartup()方法
因为Context下一级时Wapper。所以调用StandardWrapper.load()方法创建javax.servlet.Servlet。
会优先判定loadOnStartup < 0 则不执行
org.apache.catalina.core.StandardWrapper.load() 方法
创建Servlet实例的处理方法是loadServlet(); 如果有历史Servlet实例 则直接返回 单例
历史已初始化过不在执行initServlet方法: 调用Servlet的init方法(StandardWrapper 也实现了 javax.servlet.
ServletConfig接口)
以上是 SpringBoot内嵌tomcat(4)【Tomcat各组件启动时机】源码简析 的全部内容, 来源链接: utcz.com/z/514896.html