Tomcat内部处理请求详解

本文深入探讨Tomcat处理请求的详细过程,从Server、Service、Connector到ProtocolHandler,涉及Endpoint、Processor、Adapter等关键组件,揭示了请求从TCP/IP到HTTP协议的转换,以及如何进入Spring FrameworkServlet的流程。
摘要由CSDN通过智能技术生成

上一篇写了tomcat处理请求时和spring boot配合的过程,这次我们单独把tomcat处理请求的详细过程
在这里插入图片描述
一个Tomcat 中只有一个Server, 一个Server 可以包含多个Service
一个Service 只有一个Container, 但可以有多个Connectors (因为一个服务可以有多个连接,如同时提供http 和https 连接,也可以提供相同协议不同端口的连接)。
Tomcat 里的Server 由org.apache.catalina.startup.Catalina 来管理, Catalina 是整个Tomcat的管理类,它里面的三个方法load 、start 、stop 分别用来管理整个服务器的生命周期。

load 方法用于根据conf/server.xml 文件创建Server 并调用Server 的init 方法进行初始化,
start方法用于启动服务器
stop 方法用于停止服务器,
start 和stop 方法在内部分别调用了Server 的start和stop 方法, load 方法内部调用了Server 的init 方法,这三个方法都会按容器的结构逐层调用相应的方法,比如, Server 的start 方法中会调用所有的Service 中的start 方法。这就是Tomcat 生命周期的管理方式Catalina 还有个方法也很重要,那就是await 方法, Catalina 中的await 方法直接调用了Server 的await 方法,这个方法的作用是进入一个循环,让主线程不会退出。
 再说下tomcat启动问题,在springboot中,1.0版本和2.0版本启动tomcat源码是不一样的,这里是springboot2的启动:application.run()方法里:

public ConfigurableApplicationContext run(String... args) {
   
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		ConfigurableApplicationContext context = null;
		Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
		configureHeadlessProperty();
		SpringApplicationRunListeners listeners = getRunListeners(args);
		listeners.starting();
		try {
   
			//略。。。。。
			refreshContext(context);//点击进入。。。。。。。。。。。
			afterRefresh(context, applicationArguments);
			//略。。。。
		return context;
	}

进入refreshContext方法:(在spring boot1应该是EmbeddedWebApplicationContext 子类执行这个方法)

public void refresh() throws BeansException, IllegalStateException {
   
		synchronized (this.startupShutdownMonitor) {
   
			// Prepare this context for refreshing.
			prepareRefresh();
 
			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
 
			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);
 
			try {
   
				//略。。。。1​​​​​​​
				onRefresh();//点击进入
                //略
 
				
		}
	}

进入类ServletWebServerApplicationContext的onRefresh()方法:

@Override
	protected void onRefresh() {
   
		super.onRefresh();
		try {
   
			createWebServer();//点击进入。。。。。。
		}
		catch (Throwable ex) {
   
			throw new ApplicationContextException("Unable to start web server", ex);
		}
	}
 
//点击createWebServer()方法
private void createWebServer() {
   
		WebServer webServer = this.webServer;
		ServletContext servletContext = getServletContext();
		if (webServer == null && servletContext == null) {
   
            //点击进入
			ServletWebServerFactory factory = getWebServerFactory();
//点击进入
			this.webServer = factory.getWebServer(getSelfInitializer());
		}
		else if (servletContext != null) {
   
			try {
   
				getSelfInitializer().onStartup(servletContext);
			}
			catch (ServletException ex) {
   
				throw new ApplicationContextException("Cannot initialize servlet context", ex);
			}
		}
		initPropertySources();
	}

createWebServer()方法里

        //2.4.1 点击进入
        ServletWebServerFactory factory = getWebServerFactory();
      //2.4.2点击进入
        this.webServer = factory.getWebServer(getSelfInitializer());

2.4.1 getWebServerFactory() 根据上文1.1里结论会返回TomcatServletWebServerFactory。所以2.4.2的factory.getWebServer(getSelfInitializer())中的factory是指TomcatServletWebServerFactory,点击进入实现类TomcatServletWebServerFactory的getWebServer(getSelfInitializer())方法。

	public WebServer getWebServer(ServletContextInitializer... initializers) {
   
		Tomcat tomcat = new Tomcat();
		File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
		tomcat.setBaseDir(baseDir.getAbsolutePath());
		Connector connector = new Connector(this.protocol);
		tomcat.getService().addConnector(connector);
		customizeConnector(connector);
		tomcat.setConnector(connector);
		tomcat.getHost().setAutoDeploy(false);
		configureEngine(tomcat.getEngine());
		for (Connector additionalConnector : this.additionalTomcatConnectors) {
   
			tomcat.getService().addConnector(additionalConnector);
		}
		prepareContext(tomcat.getHost(), initializers);
		return getTomcatWebServer(tomcat);//点击进入。。。。。。。。
	}
//点击进入getTomcatWebServer(tomcat)
protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
   
		return new TomcatWebServer(tomcat, getPort() >= 0);//点击进入
	}
//点击new TomcatWebServer 
public TomcatWebServer(Tomcat tomcat, boolean autoStart
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值