Servlet
在java web项目中,我们无论是用什么框架,Spring MVC也好,Spring Boot也好,最后都是Servlet在起着决定性的作用。
Servlet是什么?
Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
Servlet在Web应用程序的位置如下图所示:
Servlet主要作用有:
- 读取客户端(浏览器)发送的数据 。
- 处理数据并生成结果。这个过程可能需要访问数据库,调用 Web 服务,或者直接计算得出对应的响应。平时的业务逻辑就是在这个部分实现。
- 发送处理过后的数据给客户端(浏览器)。
Servlet的运行原理
web容器收到客户端的访问请求后将进行如下处理:
- Web容器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第4步,否则,执行第2步。
- 装载并创建该Servlet的一个实例对象。
- 调用Servlet实例对象的init()方法。
- 创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
- WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。
具体来讲可以用下面的图说明:
Servlet与普通Java类的区别
针对客户端的多次Servlet请求,通常情况下,服务器只会创建一个Servlet实例对象,也就是说Servlet实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至web容器退出,servlet实例对象才会销毁。
在Servlet的整个生命周期内,Servlet的init方法只被调用一次。而对一个Servlet的每次访问请求都导致Servlet引擎调用一次servlet的service方法。
对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servlet的service()方法,service方法再根据请求方式分别调用doXXX方法。
Servlet的线程安全问题
当多个客户端并发访问同一个Servlet时,web服务器会为每一个客户端的访问请求创建一个线程,并在这个线程上调用Servlet的service方法,因此service方法内如果访问了同一个资源的话,就有可能引发线程安全问题(所以在Servlet中尽量避免使用实例变量 ,最好使用局部变量)。
Servlet如何处理多个请求访问
Servlet容器默认是采用单实例多线程的方式处理多个请求的:
- 当web服务器启动的时候(或客户端发送请求到服务器时),Servlet就被加载并实例化(只存在一个Servlet实例)
- 容器初始化化Servlet主要就是读取配置文件(例如tomcat,可以通过servlet.xml的<Connector>设置线程池中线程数目,初始化线程池通过web.xml,初始化每个参数值等等。
- 当请求到达时,Servlet容器通过调度线程(Dispatchaer Thread) 调度它管理下线程池中等待执行的线程(Worker Thread)给请求者。
- 线程执行Servlet的service方法。
- 请求结束,放回线程池,等待被调用;
从上面可以看出(好处):
- Servlet单实例,减少了产生servlet的开销;
- 通过线程池来响应多个请求,提高了请求的响应时间;
- Servlet容器并不关心到达的Servlet请求访问的是否是同一个Servlet还是另一个Servlet,直接分配给它一个新的线程。
- 如果是同一个Servlet的多个请求,那么Servlet的service方法将在多线程中并发的执行;
- 每一个请求由ServletRequest对象来接受请求,由ServletResponse对象来响应该请求;
本文暂时没有评论,来添加一个吧(●'◡'●)