Servlet-生命周期
Servlet-生命周期
步骤 | 使用方法 | 执行时间 |
---|---|---|
实例化 | 构造器 | 第一次请求/随服务器启动 |
初始化 | init | 构造完毕 |
接受请求,处理请求,服务 | service | 每次请求 |
销毁 | destory | 关闭服务 |
在Servlet被访问时,经历了 实例化对象 -> init初始化对象 -> 执行service方法
一直到服务器关闭,则会销毁此Servlet对象
@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启动时就实例化和初始化对象
<?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>
<!-- 默认值是-1,含义是 tomcat启动时不会实例化该servlet
其他正整数,含义是在tomcat在启动时,同时也是实例化该servlet的顺序
如果序号冲突,则tomcat会自动协调启动顺序-->
<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映射
<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映射来解决这个问题