如果大家对Servle容器有不懂的地方,可以看我转载的《JSP/Servlet:tomcat深入内部结构描述》这篇文章。
当开发完毕具体的Servlet类,并且部署到Web服务器上以后,是由Web服务器为我们装载并创建Servle对象的,
一般来说,Servlet可以在三种情况下装载到内存并被实例化
-Web服务器启动时
-系统管理员向Web服务器部署Servlet应用时
-通过浏览器第一次访问Servlet时
只有当首次访问时才会创建Servlet对象,以后都会使用这个对象,这样会节省大量的内存,
同时也带来的线程的安全问题
Web服务器装载一个Servlet对象时,需要明确知道Servlet的类名。比如一个名为myweb.HelloServlet的类,
当服务器装载其到内存并创建对象时将会使用Class.forName(“myweb.HelloServlet”).newInstance()方法。
Web.xml配置文件中的<servlet-class>对应的就是Servlet的全名,服务器会自动到配置文件中找到这个类全名的。
采用这中方法创建对象需要类中有个不带参数的构造器。所以我们在开发Servlet时需要提供这样的构造器,
或者干脆不写构造器,采用默认的构造器即可。该对象会保持在内存中,让它对所有的请求进行处理。
一旦Web服务器创建完Servlet对象以后,将会立即调用Servlet的init()方法,对Servlet进行初始化,
所以就算我们在Servlet中使用了默认的构造器,我们对Servlet的初始化仍然可以放到init()方法中。
这个init()方法在Servlet整个生命周期中只被调用一次,原因见上面红色字体。在任何请求传递给servlet之前,
此方法可以在不抛出异常的情况下运行完毕。
当Servlet初始化完毕以后,Servlet对象就可以响应并处理用户请求了,在Servlet的生命周期中,大部分时间是用来处理请求的。
当一个请求过来的时候,Servlet容器会对请求进行请求进行封装生成一个ServletRequest对象,
并调用servlet的public void service(ServletRequest req,ServletResponse res)方法,
并将封装好的ServletRequest和ServletResponse这个两个对象传给它,通过这二个对象我们就能实现与客户端的通信,
允许servlet响应一个请求。该方法会被调用多次,如果我们重写了Service()方法容器就会调用该方法,
不会调用doGet()或者doPost()方法,如果没有重写,容器就会判断是get请求还是post请求,然后再调用相应的方法,
这些方法是运行的在多线程状态下的。
注意:
1. The init
method must complete successfully before the servlet can receive any requests.
1.The service() method is only called after the servlet's init()
method has completed successfully
2. Servlets typically run inside multithreaded servlet containers that can handle multiple requests concurrently. Developers must be aware to synchronize access to any shared resources such as files, network connections, and as well as the servlet's class and instance variables. More information on multithreaded programming in Java is available in the Java tutorial on multi-threaded programming.
3. req - the ServletRequest object that contains the client's request
res - the ServletResponse object that contains the servlet's response
注:
Servlet的调用过程
a)解析web.xml文件中配置的Servlet的名称
b)装载类(WEB-INF/classes|WEB-INF/lib/*.jar),涉及到了JAVA类装载器的问题
c)实例化Servlet对象:Servlet ser=(Servlet)(Class.forName("servlet的类名")).newInstance();
d)调用Servlet的service()方法: ser.service(request,response);