《看透springMVC源码》之Tomcat的顶级结构及启动过程

Tomcat的顶层结构

Tomcat中最顶层的容器,代表整个服务层,Server中包含至少一个Service,用于具体提供服务。Service主要包括两部分:Connector和Container。Connector用于处理连接相关的事情,并提供Socket与request、response的转换,Container用于封装和管理Servlet,以及具体处理request请求。一个Tomcat中只有一个Server,一个Server可以包含多个Service,一个Service只有一个Container,但可以有多个Connectors(因为一个服务可以有多个连接,如同时提供http和https连接,也可以提供相同协议不同端口的连接)。

这里写图片描述

Tomcat里的Server由org.apache.catelina.startup.Catalina来管理,Catalina是整个Toncat的管理类,它里面的三个方法load、start、stop分别用来管理整个服务的生命周期,load方法用于根据conf/server.xml文件创建Server并调用Server的init方法进行初始化,start方法用于启动服务器,stop方法用于停止服务器,start和stop方法在内部分别调用了Server的start和stop方法,load方法内部调用了调用了Server的init方法,这三个方法都会按容器的结构逐层调用相应的方法,比如Server的start方法中会调用所有的Service中的start方法,Service中的start方法又会调用所有包含的Connectors和Cantainer的start方法,这样整个服务器就启动了,init和stop方法也一样,这就是Tomcat生命周期的管理方式。Catalina的await方法也很重要,它直接调用了Server的await方法,这个方法的作用是进入一个循环,让主线程不会退出。
不过Tomcat的入口main方法并不在Catalina类里,而是在org.apache.catalina.startup.Bootstrap中。Bootstrap的作用类似一个CatalinaAdaptor,具体处理过程还是使用Catalina来完成的,这么做的好处是可以把启动的入口和具体的管理类分开,从而可以很方便地创建出多种启动方式,每种启动方式只需要写一个相应的CatalinaAdapter就可以了。

Bootstrap的启动过程

boostrap是tomcat的入口,正常情况下启动Tomcat就是调用的Bootstrap的mian方法,代码如下:
这里写图片描述
这里写图片描述
首先新建了Bootrap,并执行init方法初始化;然后处理main方法传入的命令,如果agrs参数为空,默认执行start。
在init方法里初始化了CalssLoader,并用ClassLoader创建了Catalina实例,然后赋给catalinaDaemon变量,后面对命令的操作都要使用catalinaDaemon来具体执行、
对start命令的处理调用了三个方法:setAwait(true),load(args),和start()。这三个方法内部都调用了Catalina的相应方法进行具体执行,只不过是用反射来调用的。
这里写图片描述
上面的调用相当于((Catalina)catalinaDaemon).start()。setAwait和load也用类似的方法调用了Catalina中的setAwait和load方法。

Catalina的启动过程

从前面的内容可以知道,Catalina的启动主要是调用setAwait、load和start方法来完成的。setAwait方法用于设置Server启动后是否进入等待状态,如果为true则进入,否则不进入;load方法用于加载配置文件,创建并初始化Server;start方法用于启动服务器。
这里写图片描述
await属性会在start方法中的服务器启动完成之后使用它来判断是否进入等待状态。
Catalina的load方法根据conf/server.xml创建了Server对象,并赋值给server属性(具体解析操作是通过开源项目Digister完成的),然后调用了server的init方法:
这里写图片描述

Catalina的start方法主要调用了server的start方法启动服务器,并根据await属性判断是否让程序进入了等待状态:
这里写图片描述
首先判断Server是否已经存在了,如果不存在则调用load方法来初始化Server,然后调用Server的start方法来启动服务器,最后注册了关闭钩子并根据await属性判断是否进入等待状态。进入等待状态会调用await和stop两个方法,await方法直接调用了Server的await方法,Server的await方法内部会执行一个while循环,这样程序就停到了await方法,当await方法里的while循环退出时,就会执行stop方法,从而关闭服务器。

Server的启动过程

Server接口中提供addServer(Service service)、removeService(Service service)来添加和删除Service,Server的init方法和start方法分别循环调用了每个Service的init方法和start方法来启动所有Service。
Server的默认实现是org.apache.catalina.core.StandardSrever,StandardServer继承自LifecycleMBeanBase,LifecycleMBeanBase又继承自LifecycleBase,init和start方法就定义在了LifecycleBase中,LifecycleBase里的init方法和start方法有调用initInternal方法和startInternal方法,这两个方法都是模板方法,由子类具体实现,所以调用StandardServer的init和start方法时会执行StandardServer自己的initInternal和startInternal方法,这就是Tomcat生命周期的管理方式。
这里写图片描述

除了startInternal和initInternal方法,StandardServer中还实现了await方法,Catalina中就是调用它让服务器进入等待状态的:
这里写图片描述
这里写图片描述
处理的大概逻辑是首先判断端口号port,然后根据port的值分为三种处理方法:
1. port为-2,则会直接退出,不进入循环、
2. port为-1,则会进入一个while(!stopAwait) 的循环,并且在内部没有break跳出的语句,stopAwait标志只有调用了stop方法才会设置为ture,所以port为-1时只有在外部调用stop方法才会退出循环。
3. port为其他值,则也会进入一个while(!stopAwait)的循环,不过同时会在port所在端口启动一个ServerScoket来监听关闭命令,如果收到了则会使用brake跳出循环。
这里的端口port和关闭命令shutdown是在conf/server.xml文件中配置Server时设置的:
这里写图片描述
这时会在8005端口监听“SHUTDOWN”命令,如果接收到了就会关闭Tomcat。如果不想使用网络命令来关闭服务器可以将端口设置为-1。

Service的启动过程

Service的默认实现是org.apache.catalina.core.StandardService,Standardservice也继承自LifecycleMBeanBase类,所以init和start方法最终也会调用initInternal和startInternal方法:
这里写图片描述
这里写图片描述
可以看到,StandardService中的initInternal和startInternal方法主要调用cantainer、executors、mapperListener、connectors的init和start方法。container和connectors前面已经介绍过,mapperListener是mapper
的监听器,可以监听container容器的变化,executors是用在connectors中管理线程的线程池,在server.xml配置文件综中有参考用法,不过默认是注释起来的:
这里写图片描述
这样Connector就配置了一个叫tomcatThreadPool的线程池,最多可以同时启动150个线程,最少要有4个可用线程。
至此整个Tomcat服务器就启动了:
这里写图片描述

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
引用\[1\]:在配置文件springmvc-servlet.xml中,我们创建了一个HelloController类,并使用@Controller注解标记为控制器。在该类中,我们使用@RequestMapping注解来处理请求,并将"hello SpringMVC"添加到Model中,然后返回"hello"作为视图名称。\[1\] 引用\[2\]:在配置文件中,我们配置了SpringMVC的前端控制器DispatcherServlet,并指定了SpringMVC配置文件的位置和名称为classpath:springMVC.xml。此外,我们还设置了DispatcherServlet的初始化时间为服务器启动时。同时,我们将DispatcherServlet映射到根路径"/",以处理所有的请求。\[2\] 引用\[3\]:在HelloController类中,我们使用@RequestMapping注解将根路径"/"映射到index()方法。在该方法中,我们返回"index"作为视图名称。\[3\] 当你的SpringMVC项目在Tomcat启动时出现爆红的情况,可能是由于以下几个原因: 1. 缺少相关的依赖库:请确保你的项目中已经正确引入了SpringMVC的相关依赖库,比如spring-webmvc等。 2. 配置文件错误:请检查你的配置文件是否正确,比如springmvc-servlet.xml和springMVC.xml是否存在且配置正确。 3. 控制器类错误:请确保你的控制器类中的注解和方法都正确,比如@Controller和@RequestMapping注解是否正确使用,并且方法的返回类型和参数是否符合要求。 如果以上步骤都没有解决问题,你可以尝试重新构建项目或者查看Tomcat的日志文件以获取更详细的错误信息,从而找到解决方案。 #### 引用[.reference_title] - *1* [记录一次IDEA配置Tomcat并创建SpringMVC项目](https://blog.csdn.net/qq_34075488/article/details/113251525)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [SpringMVC的搭建idea2021、tomcat8.5](https://blog.csdn.net/m0_62208814/article/details/125932099)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值