关于Servlet的一些知识

servlet的生命周期就是从servlet出现到销毁的全过程。主要分为以下几个阶段:
加载类—>实例化(为对象分配空间)—>初始化(为对象的属性赋值)—>请求处理(服务阶段)—>销毁
服务器启动时(web.xml中配置load-on-startup=1,默认为0)或者第一次请求该servlet时,就会初始化一个Servlet对象,也就是会执行初始化方法init(ServletConfig conf),该servlet对象去处理所有客户端请求,service(ServletRequest req,ServletResponse res)方法中执行,最后服务器关闭时,才会销毁这个servlet对象,执行destroy()方法。其中加载阶段无法观察,但是初始化、服务、销毁阶段是可以观察到的。

为什么创建的servlet是继承自httpServlet,而不是直接实现Servlet接口?
解答:
首先看下源码,HttpServlet的继承结构:
public abstract class HttpServlet extends GenericServlet
HttpServlet继承了GenericServlet,GenericServlet是一个通用的Servlet,那么他的作用是什么呢?大概的就是将实现Servlet接口的方法,简化编写servlet的步骤
public abstract class GenericServlet implements Servlet,ServletConfig,Serializable{}
实现了Servlet接口和ServletConfig接口
Servlet接口的内容:

public interface Servlet {
	void init(ServletConfig var1) throws  ServletException;
	ServletConfig getServletConfig();
	void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
	String getServletInfo();
	void destroy();
}

从这里可以看到,Servlet生命周期的三个关键方法,init、service、destroy。还有另外两个方法,一个getServletConfig()方法来获取ServletConfig对象,ServletConfig对象可以获取到Servlet的一些信息,ServletName、ServletContext、InitParameter、InitParameterNames、通过查看ServletConfig这个接口就可以知道

public interface ServletConfig {
	String getServletName();
	ServletContext getServletContext();
	String getInitParameter(String var1);
	Enumeration<String> getInitParameterNames();
}

其中ServletContext对象是servlet上下文对象,功能有很多,获得了ServletContext对象,就能获取大部分我们需要的信息,比如获取servlet的路径等方法。到此,就知道了Servlet接口中的内容和作用,总结起来就是,三个生命周期运行的方法,获取ServletConfig,而通过ServletConfig又可以获取到ServletContext。而GenericServlet实现了Servlet接口后,也就说明我们可以直接继承GenericServlet,就可以使用上面我们所介绍Servlet接口中的那几个方法了,能拿到ServletConfig,也可以拿到ServletContext,不过那样太麻烦,不能直接获取ServletContext,所以GenericServlet除了实现Servlet接口外,还实现了ServletConfig接口,那样,就可以直接获取ServletContext了。
init方法存在两个,一个带参,一个无参:

private transient ServletConfig config;
public void init(ServletConfig config) throws ServletException {
		this.config = config;
		this.init();
	}
	public void init() throws ServletException {
	}
	public ServletConfig getServletConfig() {
		return this.config;
	}

缺省的servlet的作用为:凡是在web.xml文件总找不到匹配的元素的URL,他们的方位请求都将交给缺省的servlet处理。也就是说,缺省的servlet用于处理所有其他servlet不处理的访问请求。当访问tomcat服务中的某个静态html文件和图片时,实际上是在访问这个缺省的servlet

<servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/</url-pattern>
</servlet-mapping>

servlet的映射路径为一个(/),称之为缺省的servlet。则这个servlet就成为了当前web应用程序的缺省servlet。

设计线程安全的Servlet:
1、实现 SingleThreadModel 接口
如果一个Servlet被这个接口指定,那么在这个Servlet中的service方法将不会有两个线程被同时执行,当然也就不存在线程安全的问题。这种方法只要将前面的Concurrent Test类的类头定义更改为:
public class Concurrent Test extends HttpServlet implements SingleThreadModel {}
因为引起大量系统开销,不建议使用
2、同步对共享数据的操作
使用synchronized 关键字能保证一次只有一个线程可以访问被保护的区段,在本论文中的Servlet可以通过同步块操作来保证线程的安全。同步后的代码如下:

Public class Concurrent Test extends HttpServlet {
    …………
username = request.getParameter ("username");
synchronized (this){
output = response.getWriter ();
try {
    Thread. Sleep (5000);
} Catch (Interrupted Exception e){}
    output.println("用户名:"+Username+"
");}}}

3、避免使用实例变量
只要在Servlet里面的任何方法里面都不使用实例变量,那么该Servlet就是线程安全的。修正上面的Servlet代码,将实例变量改为局部变量实现同样的功能,代码如下:

public class Concurrent Test extends HttpServlet {
    public void service (HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        PrintWriter output;
        String username;
        response.setContentType ("text/html; charset=gb2312");
        ……}}

Servlet的线程安全问题只有在大量的并发访问时才会显现出来,并且很难发现,因此在编写Servlet程序时要特别注意。线程安全问题主要是由实例变量造成的,因此在Servlet中应避免使用实例变量。如果应用程序设计无法避免使用实例变量,那么使用同步来保护要使用的实例变量,但为保证系统的最佳性能,应该同步可用性最小的代码路径。
ServletConfig的作用
1.通过ServletConfig获取Servlet的初始化参数
当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,我们通过ServletConfig对象就可以得到当前servlet的初始化参数信息。
2.WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值