Servlet-生命周期
| 步骤 |
使用方法 |
执行时间 |
| 实例化 |
构造器 |
第一次请求/随服务器启动 |
| 初始化 |
init |
构造完毕 |
| 接受请求,处理请求,服务 |
service |
每次请求 |
| 销毁 |
destory |
关闭服务 |
在Servlet被访问时,经历了 实例化对象 -> init初始化对象 -> 执行service方法
一直到服务器关闭,则会销毁此Servlet对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @WebServlet("/servletLifeCycle") public class ServletLifeCycle extends HttpServlet { public ServletLifeCycle() { System.out.println("构造器"); }
@Override public void init(ServletConfig config) throws ServletException { System.out.println("初始化"); }
@Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("service方法"); }
@Override public void destroy() { System.out.println("销毁"); } }
|
由此次实验,我们可以知道以下结论
- Servlet在Tomcat中是单例的:既一个Servlet只会实例化一个对象
- Servlet不会只被一个客户端访问,每一个客户端都是一个线程,而Servlet的成员变量在多个线程栈之中时共享的,所以强烈建议不要在service方法中修改成员变量,避免线程安全问题
Servlet的对象
Servlet的对象是在其第一次被访问时实例化和初始化
我们可以通过调整web.xml的load-on-startup标签,让其与Tomcat启动时就实例化和初始化对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd" version="6.0"> <servlet> <servlet-name>servletLifeCycle</servlet-name> <servlet-class>com.xiaobai.servlet.ServletLifeCycle</servlet-class>
<load-on-startup>6</load-on-startup> </servlet> <servlet-mapping> <servlet-name>servletLifeCycle</servlet-name> <url-pattern>/servletLifeCycle</url-pattern> </servlet-mapping> </web-app>
|
注:Tomcat的配置文件中web.xml里已经占用了很多启动的序号,这里推荐用户自定义的序号是从6开始
那么我们也可以调整注解的参数
int loadOnStartup() default -1;
@WebServlet(value = “/servletLifeCycle”,loadOnStartup = 6)
default-servlet
在Tomcat的web.xml中,配置了这样的一个Sevlet映射
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <servlet> <servlet-name>default</servlet-name> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>listings</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
|
当客户端访问静态资源时,Tomcat仍然会将请求按照Servlet的寻找方式来寻找
当客户端没查到精确匹配的Servlet时,就会将请求交给DefaultServlet来处理
这个DefaultServlet配置了模糊匹配全部(除了.jsp文件外)
DefaultServlet会寻找其对应的具体文件,再使用IO流读取此文件,并将此文件放到response对象的响应体中
并根据文件的拓展名选择合适的MIME(媒体类型),使用response设置Content-Type响应头
再读取文件大小,使用response设置Content-Length响应头
最后将response对象转换成响应报文发送回客户端
SpringMVC
在SpringMVC中,会默认使default-servlet失效,如果不单独进行额外的配置,会导致无法访问其网站内的所有静态资源
我们可以通过在其中重新配置default-servlet映射来解决这个问题