深入拆解 Tomcat & Jetty
李号双
eBay 技术主管
38890 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 45 讲
开篇词 (1讲)
深入拆解 Tomcat & Jetty
15
15
1.0x
00:00/00:00
登录|注册

03 | 你应该知道的Servlet规范和Servlet容器

Listener
Filter
ServletContext
扩展机制
Web应用
工作流程
destroy
getServletInfo
service
getServletConfig
init
Servlet容器与Spring容器的关系
Filter与Listener
Servlet规范与Tomcat、Jetty
Servlet容器与HTTP服务器
Servlet接口与业务类
Servlet容器
Servlet接口
思考
关系
Servlet规范

该思维导图由 AI 生成,仅供参考

通过专栏上一期的学习我们知道,浏览器发给服务端的是一个 HTTP 格式的请求,HTTP 服务器收到这个请求后,需要调用服务端程序来处理,所谓的服务端程序就是你写的 Java 类,一般来说不同的请求需要由不同的 Java 类来处理。
那么问题来了,HTTP 服务器怎么知道要调用哪个 Java 类的哪个方法呢。最直接的做法是在 HTTP 服务器代码里写一大堆 if else 逻辑判断:如果是 A 请求就调 X 类的 M1 方法,如果是 B 请求就调 Y 类的 M2 方法。但这样做明显有问题,因为 HTTP 服务器的代码跟业务逻辑耦合在一起了,如果新加一个业务方法还要改 HTTP 服务器的代码。
那该怎么解决这个问题呢?我们知道,面向接口编程是解决耦合问题的法宝,于是有一伙人就定义了一个接口,各种业务类都必须实现这个接口,这个接口就叫 Servlet 接口,有时我们也把实现了 Servlet 接口的业务类叫作 Servlet。
但是这里还有一个问题,对于特定的请求,HTTP 服务器如何知道由哪个 Servlet 来处理呢?Servlet 又是由谁来实例化呢?显然 HTTP 服务器不适合做这个工作,否则又和业务类耦合了。
于是,还是那伙人又发明了 Servlet 容器,Servlet 容器用来加载和管理业务类。HTTP 服务器不直接跟业务类打交道,而是把请求交给 Servlet 容器去处理,Servlet 容器会将请求转发到具体的 Servlet,如果这个 Servlet 还没创建,就加载并实例化这个 Servlet,然后调用这个 Servlet 的接口方法。因此 Servlet 接口其实是 Servlet 容器跟具体业务类之间的接口下面我们通过一张图来加深理解。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Servlet规范和Servlet容器在Java Web开发中扮演着重要角色。Servlet规范定义了Servlet接口和Servlet容器的工作原理,实现了HTTP服务器与业务类的解耦。开发者可以通过实现Servlet接口的业务类来专注于业务逻辑的开发,而Servlet容器负责加载和管理这些业务类。文章还介绍了Servlet接口的定义和重要方法,以及Servlet容器的工作流程和Web应用的目录结构。此外,Servlet规范提供了扩展机制Filter和Listener,用于定制化处理请求和响应以及监听Web应用的事件。总的来说,Servlet规范和Servlet容器为Java Web开发提供了标准化的解决方案,同时也提供了灵活的扩展机制,使得开发者能够更好地理解和应用Tomcat和Jetty等具体的Servlet容器实现。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《深入拆解 Tomcat & Jetty 》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(104)

  • 最新
  • 精选
  • 天琊
    置顶
    文章中提到 1.SpringMVC 容器实在DispatcherServlet中init方法里创建的。 2.Spring 容器是通过Listener创建的 a、就是说SpringMVC容器和Spring容器还不一样,那么他们是什么关系? b、他们和Servlet容器又是啥关系?

    作者回复: Tomcat&Jetty在启动时给每个Web应用创建一个全局的上下文环境,这个上下文就是ServletContext,其为后面的Spring容器提供宿主环境。 Tomcat&Jetty在启动过程中触发容器初始化事件,Spring的ContextLoaderListener会监听到这个事件,它的contextInitialized方法会被调用,在这个方法中,Spring会初始化全局的Spring根容器,这个就是Spring的IoC容器,IoC容器初始化完毕后,Spring将其存储到ServletContext中,便于以后来获取。 Tomcat&Jetty在启动过程中还会扫描Servlet,一个Web应用中的Servlet可以有多个,以SpringMVC中的DispatcherServlet为例,这个Servlet实际上是一个标准的前端控制器,用以转发、匹配、处理每个Servlet请求。 Servlet一般会延迟加载,当第一个请求达到时,Tomcat&Jetty发现DispatcherServlet还没有被实例化,就调用DispatcherServlet的init方法,DispatcherServlet在初始化的时候会建立自己的容器,叫做SpringMVC 容器,用来持有Spring MVC相关的Bean。同时,Spring MVC还会通过ServletContext拿到Spring根容器,并将Spring根容器设为SpringMVC容器的父容器,请注意,Spring MVC容器可以访问父容器中的Bean,但是父容器不能访问子容器的Bean, 也就是说Spring根容器不能访问SpringMVC容器里的Bean。说的通俗点就是,在Controller里可以访问Service对象,但是在Service里不可以访问Controller对象。

    2019-05-16
    24
    388
  • Monday
    基于思考题,我在梦中醒来,觉得servlet容器管理的是servlet(把controller也理解成了servlet),spring容器则是管理service,DAO这类bean。这样理解的话springMVC不就是多余的了吗?但是我们项目中都有使用springMVC,存在即合理,所以我的理解是有误的。于是想老师帮忙给出以下三张图。非常感谢, 1,恳求老师能给出servlet,spring,springMVC三个容器的关系图。 2,恳求老师给出初始化三个容器的顺序图 3,恳求老师给出tomcat在响应客户端请求时,以上3个容器的分工以及各自是在什么时候产生作用的。类似于第2节http必知必会中,用户在浏览器输入url到最后浏览器返回展示的那样的11步的图,并做出每一步的解释。 PS:本文通读不少于3遍,收获颇丰。提这个问题是手机敲的字,和整理提问思路一起花了半小时。

    作者回复: 本来想自己画一张,但是在网上找了一下,找到这张图,蛮清楚的: https://blog.csdn.net/zhanglf02/article/details/89791797

    2019-05-17
    2
    50
  • neohope
    Servlet容器,是用于管理Servlet生命周期的。 Spring容器,是用于管理Spring Bean生命周期的。 SpringMVC容器,适用于管理SpringMVC Bean生命周期的。 Tomcat/Jetty启动,对于每个WebApp,依次进行初始化工作: 1、对每个WebApp,都有一个WebApp ClassLoader,和一个ServletContext 2、ServletContext启动时,会扫描web.xml配置文件,找到Filter、Listener和Servlet配置 3、如果Listener中配有spring的ContextLoaderListener 3.1、ContextLoaderListener就会收到webapp的各种状态信息。 3.3、在ServletContext初始化时,ContextLoaderListener也就会将Spring IOC容器进行初始化,管理Spring相关的Bean。 3.4、ContextLoaderListener会将Spring IOC容器存放到ServletContext中 4、如果Servlet中配有SpringMVC的DispatcherServlet 4.1、DispatcherServlet初始化时(其一次请求到达)。 4.2、其中,DispatcherServlet会初始化自己的SpringMVC容器,用来管理Spring MVC相关的Bean。 4.3、SpringMVC容器可以通过ServletContext获取Spring容器,并将Spring容器设置为自己的根容器。而子容器可以访问父容器,从而在Controller里可以访问Service对象,但是在Service里不可以访问Controller对象。 4.2、初始化完毕后,DispatcherServlet开始处理MVC中的请求映射关系。 有一个很坑问题,Servlet默认是单例模式的,Spring的Bean默认是单例模式的,那Spring MVC是如何处理并发请求的呢?

    作者回复: DispatcherServlet中的成员变量都是初始化好后就不会被改变了,所以是线程安全的,那“可见性”怎么保证呢? 这是由Web容器比如Tomcat来做到的,Tomcat在调用Servlet的init方法时,用了synchronized。 private synchronized void initServlet(Servlet servlet) {...}

    2019-05-19
    9
    47
  • 而立斋
    spring容器中还包含许多的子容器,其中springmvc容器就是其中常用的一个,文中的DispatcherServlet就是springmvc容器中的servlet接口,也是springmvc容器的核心类。spring容器主要用于整个Web应用程序需要共享的一些组件,比如DAO、数据库的ConnectionFactory等,springmvc的容器主要用于和该Servlet相关的一些组件,比如Controller、ViewResovler等。至此就清楚了spring容器内部的关系,那servlet容器跟spring容器又有什么关系呢?有人说spring容器是servlet容器的子容器,但是这个servlet容器到底是tomcat实现的容器呢,还是jetty实现的容器呢?所以我觉得spring容器与servlet容器他们之间并没有直接的血缘关系,可以说spring容器依赖了servlet容器,spring容器的实现遵循了Servlet 规范。不知道这么理解是可以,还请老师给予指导?

    作者回复: 对的,说的很好

    2019-05-16
    3
    39
  • Geek_ebda96
    老师,spring容器指的是spring本身的ioc容器吧,是用来管理所有的bean,servlet本身会把sping的容器设置到上下文中,而spring mvc的容器dispatch servlet相当于是一个具体的servlet的实现,然后会创建一个全局的上下文application context spring的ioc容器会注入到这个上下文中,后面通过上下文getbean,其实是先找到上下文中的ioc容器,然后再从这个容器拿到具体的bean,这是不是对的?

    作者回复: 不太准确哦,首先我们明确一点,Spring和SpringMVC分别有自己的IOC容器或者说上下文。 为什么要分成两个容器呢?为了职责划分清晰。 SpringMVC的容器直接管理跟DispatcherServlet相关的Bean,也就是Controller,ViewResolver等,并且SpringMVC容器是在DispacherServlet的init方法里创建的。而Spring容器管理其他的Bean比如Service和DAO。 并且SpringMVC容器是Spring容器的子容器,所谓的父子关系意味着什么呢,就是你通过子容器去拿某个Bean时,子容器先在自己管理的Bean中去找这个Bean,如果找不到再到父容器中找。但是父容器不能到子容器中去找某个Bean。 其实这个套路跟JVM的类加载器设计有点像,不同的类加载器也为了隔离,不过加载顺序是反的,子加载器总是先委托父加载器去加载某个类,加载不到再自己来加载。

    2019-05-17
    2
    32
  • jaryoung
    没有Spring boot以前,他们的关系为tomcat抱着Spring的关系,有了Spring boot之后他们关系刚好反过来。

    作者回复: 对的

    2019-08-14
    3
    30
  • xxxxL
    请问service方法为什么把request和response都当作输入参数,而不是输入参数只有request,response放到返回值里呢?

    作者回复: 方便责任链模式下层层传递

    2019-05-31
    25
  • 菜鸡小王子
    老师问一下 tomcat分为http服务器+sevlet服务器 这个http服务器怎么理解呢

    作者回复: 就是处理网络通信,接收到HTTP请求后,把HTTP请求数据转成标准的ServletRequest对象,再把这个对象交给Servlet容器去处理

    2019-05-30
    16
  • inrtyx
    老题,问下。springmvc如何实现url到方法的映射

    作者回复: 通过扫描注解,将所有带有@Controller和@RequestMapping注解的类收集起来,统一保存到map里,请求来了通过查找这个map找到相应的类。

    2019-05-23
    15
  • 蓝士钦
    课后思考: Servlet容器与Spring容器的关系: 1.Servlet容器管理Servlet对象 2.Spring容器管理Spring 的Bean对象(Service和Dao) 3.SpringMVC容器管理 Controller的Bean对象,本质上也是Servlet对象。Servlet容器和SpringMVC容器通过web.xml配置文件产生交集。 Spring容器管理所有的Bean并且包括SpringMVC容器。 疑问: 为什么SpringMVC要实现自己的容器,并且和Spring容器为父子关系,直接用Spring容器不可以吗?Spring是如何区分Bean属于哪个容器的呢?

    作者回复: Spring和SpringMVC用不同的容器是为了隔离管理的Bean,各管各的,职责明确。并且通过父子关系,使得SpringMVC容器可以从父亲Spring容器那里拿Bean,因为Spring容器管理的是公共的Bean。 当然可以用同一个容器来管理,SpringBoot就是这样做的。 Spring和SpringMVC是通过配置文件来明确指定各自管理的Bean

    2019-06-11
    2
    14
收起评论
显示
设置
留言
99+
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部