DispatcherServlet
自动装配EnableAutoConfiguration-->DispatcherServletAutoConfiguration,使用注解 @Conditional @Bean,new出来的对象,DispatcherServlet dispatcherServlet = new DispatcherServlet();然后组装成DispatcherServletRegistrationBean对象(ServletRegistrationBean<DispatcherServlet>--DynamicRegistrationBean<Dynamic>--RegistrationBean--ServletContextInitializer)放在容器中备用,ServletContextInitializer可以支持Servlet、Filter、EventListener等
AnnotationConfigServletWebServerApplicationContext
1.springboot启动时,反射出AnnotationConfigServletWebServerApplicationContext实例对象
2.AnnotationConfigServletWebServerApplicationContext-->ServletWebServerApplicationContext.onRefresh()覆盖了父类GenericWebApplicationContext.onRefresh()的方法,onRefresh()方法中ServletWebServerApplicationContext.createWebServer();创建web服务器
3.容器刷新的时候,refresh()方法中又调用onRefresh()方法
Tomcat
1.ServletWebServerApplicationContext.createWebServer()方法中,取到容器中的工厂bean对象ServletWebServerFactory来创建web服务器,工厂bean是通过EnableAutoConfiguration-->EmbeddedServletContainerAutoConfiguration-->TomcatEmbeddedServletContainerFactory注入时容器中的,通过@ConditionalOnClass({Servlet.class, Tomcat.class})配合,注入了tomcat服务器的工厂类对象
2.通过ServletWebServerFactory工厂对象来取服务器的对象,servletWebServerFactory.getWebServer(new ServletContextInitializer[]{this.getSelfInitializer()}); 传入数组对象,等tomcat的servlet容器实例化好后再调回来:从spring容器中取出ServletContextInitializer对象(上面放入的DispatcherServletRegistrationBean对象),执行.onStartup(servletContext)方法(tomcat调用的),spi思想(A要调用B中的C,此时A还不知道C是什么样子的,只能让B组装好C,放在固定的位置,让A来调用,A和B之前解耦)
1).Tomcat tomcat = new Tomcat()时,new StandardServer(); new StandardService(); server.addService(service);connector(默认配置的Http11NioProtocol);new StandardHost(); new StandardEngine();new TomcatEmbeddedContext()--StandardContext类型的,取到spring容器中的ServletContextInitializer对象设置属性,创建了一整套tomcat相关的组件;然后initialize方法初始化,start启动
2).tomcat的生命周期LifecycleBase.start()--startInternal()--StandardContext.startInternal()--servletContextInitializer.onStartup(servletContext);主要是将dispatcherServlet加入到servletContext中(tomcat的servlet容器),也就是StandardContext中的StandardWrapper对象属性Servlet instance(dispatcherServlet为单例对象,所以这里直接设置对象)
tomcat启动后,主要功能:
网络通信EndPoint,tcp/ip,socket监听端口,接收请求
应用层协议的解析Processor,将收到的字节流解码成http文本格式
Adapter适配器,Tomcat的Request/Response与ServletRequest/ServletResponse对象的转化
Servlet容器,将对应的Request请求分发到相应的Servlet中,让servlet处理业务逻辑,返回Response对象


Acceptor线程组(默认1个)启动,死循环运行,主要用于监听连接,将Socket封装成PollerEvent转交给Poller线程池任务队列中
Poller线程组启动,处理队列中的事件任务
NioEndpoint.processKey()
AbstractEndpoint.processSocket()
SocketProcessorBase.doRun()-->NioEndpoint.doRun()-->getHandler().process(socketWrapper, event)-->state = processor.process(wrapper, status)
AbstractProcessorLight state = service(socketWrapper);
Http11Processor getAdapter().service(request, response);
CoyoteAdapter connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);
StandardEngineValve.invoke()
StandardWrapperValve.invoke()最后一个管道阀门方法中,找到分配servlet = wrapper.allocate()-->StandardWrapper.loadServlet()
dispatcherServlet初始化组件信息
StandardWrapper.loadServlet()-->servlet.init(servletConfig)-->GenericServlet.init()-->HttpServletBean.init()
-->HttpServletBean.initServletBean()-->FrameworkServlet.initServletBean()-->FrameworkServlet.initWebApplicationContext()
-->DispatcherServlet.onRefresh(wac)-->DispatcherServlet.initStrategies(context);然后开始进行一系列的组装DispatcherServlet值
filterChain,过滤
dispatcherServlet.service();//doGet, doPost
StandardWrapper.loadServlet()-->servlet.init(servletConfig)-->GenericServlet.init()-->HttpServletBean.init()-->HttpServletBean.initServletBean()-->FrameworkServlet.initServletBean()-->FrameworkServlet.initWebApplicationContext()-->DispatcherServlet.onRefresh(wac)-->DispatcherServlet.initStrategies(context);然后开始进行一系列的组装DispatcherServlet值
- 请求发送到本机的8080端口,被在那里监听的HTTP/1.1的连接器Connector获得
- 连接器Connector将字节流转换为容器所需要的
ServletRequest对象给同级Service下的容器模块Engine进行处理 - Engine获得地址
http://localhost:8080/buxuewushu/add。匹配他下面的Host主机 - 匹配到名为localhost的Host(就算此时请求为具体的ip,没有配置相应的Host,也会交给名为localhost的Host进行处理,因为他是默认的主机)
- Host匹配到路径为
/buxuewushu的Context,即在webapp下面找到相应的文件夹 - Context匹配到URL规则为*.do的servlet,对应为某个Servlet类
- 调用其
doGet或者doPost方法 - Servlet执行完以后将对象返回给Context
- Context返回给Host
- Host返回给Engine
- Engine返回给连接器Connector
- 连接器Connector将对象解析为字节流发送给客户端