Tomcat请求处理(七) - Servlet实例的调用

org.apache.jasper.servlet.JspServletWrapper的service()方法包括了编译,载入和执行Servlet几个步骤,如下所示:

Java代码 Tomcat请求处理(七) - Servlet实例的调用 - guoyang1982 - 游龙

  1. public void service(HttpServletRequest request, HttpServletResponse response, boolean precompile)   
  2.         throws ServletException, IOException, FileNotFoundException {   
  3.   
  4.     try {   
  5.         if (ctxt.isRemoved()) {   
  6.             throw new FileNotFoundException(jspUri);   
  7.         }   
  8.   
  9.         if ((available > 0L) && (available < Long.MAX_VALUE)) {   
  10.             if (available > System.currentTimeMillis()) {   
  11.                 response.setDateHeader("Retry-After", available);   
  12.                 response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, Localizer   
  13.                         .getMessage("jsp.error.unavailable"));   
  14.                 return;   
  15.             } else {   
  16.                 // Wait period has expired. Reset.   
  17.                 available = 0;   
  18.             }   
  19.         }   
  20.   
  21.         // (1) 编译   
  22.         if (options.getDevelopment() || firstTime) {   
  23.             synchronized (this) {   
  24.                 firstTime = false;   
  25.   
  26.                 // The following sets reload to true, if necessary   
  27.                 ctxt.compile();   
  28.             }   
  29.         } else {   
  30.             if (compileException != null) {   
  31.                 // Throw cached compilation exception   
  32.                 throw compileException;   
  33.             }   
  34.         }   
  35.   
  36.         // (2) 载入Servlet类文件   
  37.         getServlet();   
  38.   
  39.         // 如果是预编译,那么直接返回   
  40.         if (precompile) {   
  41.             return;   
  42.         }   
  43.   
  44.     } catch (ServletException ex) {   
  45.         if (options.getDevelopment()) {   
  46.             throw handleJspException(ex);   
  47.         } else {   
  48.             throw ex;   
  49.         }   
  50.     } catch (IOException ex) {   
  51.         if (options.getDevelopment()) {   
  52.             throw handleJspException(ex);   
  53.         } else {   
  54.             throw ex;   
  55.         }   
  56.     } catch (IllegalStateException ex) {   
  57.         if (options.getDevelopment()) {   
  58.             throw handleJspException(ex);   
  59.         } else {   
  60.             throw ex;   
  61.         }   
  62.     } catch (Exception ex) {   
  63.         if (options.getDevelopment()) {   
  64.             throw handleJspException(ex);   
  65.         } else {   
  66.             throw new JasperException(ex);   
  67.         }   
  68.     }   
  69.   
  70.     try {   
  71.   
  72.         // (3) 调用Servlet处理请求   
  73.         if (theServlet instanceof SingleThreadModel) {   
  74.             synchronized (this) {   
  75.                 theServlet.service(request, response);   
  76.             }   
  77.         } else {   
  78.             theServlet.service(request, response);   
  79.         }   
  80.   
  81.     } catch (UnavailableException ex) {   
  82.         String includeRequestUri = (String) request   
  83.                 .getAttribute("javax.servlet.include.request_uri");   
  84.         if (includeRequestUri != null) {   
  85.             throw ex;   
  86.         } else {   
  87.             int unavailableSeconds = ex.getUnavailableSeconds();   
  88.             if (unavailableSeconds <= 0) {   
  89.                 unavailableSeconds = 60; // Arbitrary default   
  90.             }   
  91.             available = System.currentTimeMillis() + (unavailableSeconds * 1000L);   
  92.             response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, ex.getMessage());   
  93.         }   
  94.     } catch (ServletException ex) {   
  95.         if (options.getDevelopment()) {   
  96.             throw handleJspException(ex);   
  97.         } else {   
  98.             throw ex;   
  99.         }   
  100.     } catch (IOException ex) {   
  101.         if (options.getDevelopment()) {   
  102.             throw handleJspException(ex);   
  103.         } else {   
  104.             throw ex;   
  105.         }   
  106.     } catch (IllegalStateException ex) {   
  107.         if (options.getDevelopment()) {   
  108.             throw handleJspException(ex);   
  109.         } else {   
  110.             throw ex;   
  111.         }   
  112.     } catch (Exception ex) {   
  113.         if (options.getDevelopment()) {   
  114.             throw handleJspException(ex);   
  115.         } else {   
  116.             throw new JasperException(ex);   
  117.         }   
  118.     }   
  119. }  

#compile()方法实现了对JSP文件向java类(Servlet)的编译,源代码如下所示:

Java代码 Tomcat请求处理(七) - Servlet实例的调用 - guoyang1982 - 游龙

  1. public void compile() throws JasperException, FileNotFoundException {   
  2.     // 创建"jspCompiler"的实例   
  3.     createCompiler();   
  4.     // 判断是否过期,即是否需要重新编译,这个方法中主要用源代码和编译后的文件的修改时间等因素进行判断   
  5.     if (jspCompiler.isOutDated()) {   
  6.         try {   
  7.             jspCompiler.removeGeneratedFiles();   
  8.             jspLoader = null;   
  9.             // 执行编译   
  10.             jspCompiler.compile();   
  11.             // 设定reload标志为true,让#getServlet()方法载入新的类   
  12.             jsw.setReload(true);   
  13.             jsw.setCompilationException(null);   
  14.         } catch (JasperException ex) {   
  15.             // Cache compilation exception   
  16.             jsw.setCompilationException(ex);   
  17.             throw ex;   
  18.         } catch (Exception ex) {   
  19.             JasperException je = new JasperException(   
  20.                         Localizer.getMessage("jsp.error.unable.compile"),   
  21.                         ex);   
  22.             // Cache compilation exception   
  23.             jsw.setCompilationException(je);   
  24.             throw je;   
  25.         }   
  26.     }   
  27. }  

可以看出,JSP页面没有修改的前提下Tomcat是不会对JSP进行多次编译的,只在第一次调用它的时候编译。

看完#compile()后,再来看一下#getServlet(),它载入了前面编译生成的Servlet类。

Java代码 Tomcat请求处理(七) - Servlet实例的调用 - guoyang1982 - 游龙

  1. public Servlet getServlet() throws ServletException, IOException, FileNotFoundException {   
  2.     if (reload) {   
  3.         synchronized (this) {   
  4.             if (reload) {   
  5.                 // 销毁旧的Servlet   
  6.                 destroy();   
  7.   
  8.                 Servlet servlet = null;   
  9.   
  10.                 try {   
  11.                     // 载入Servlet   
  12.                     servletClass = ctxt.load();   
  13.                     servlet = (Servlet) servletClass.newInstance();   
  14.                     AnnotationProcessor annotationProcessor = (AnnotationProcessor) config   
  15.                             .getServletContext().getAttribute(   
  16.                                     AnnotationProcessor.class.getName());   
  17.                     if (annotationProcessor != null) {   
  18.                         annotationProcessor.processAnnotations(servlet);   
  19.                         annotationProcessor.postConstruct(servlet);   
  20.                     }   
  21.                 } catch (IllegalAccessException e) {   
  22.                     throw new JasperException(e);   
  23.                 } catch (InstantiationException e) {   
  24.                     throw new JasperException(e);   
  25.                 } catch (Exception e) {   
  26.                     throw new JasperException(e);   
  27.                 }   
  28.                 // Servlet初始化   
  29.                 servlet.init(config);   
  30.   
  31.                 if (!firstTime) {   
  32.                     ctxt.getRuntimeContext().incrementJspReloadCount();   
  33.                 }   
  34.   
  35.                 theServlet = servlet;   
  36.                 // reload值复原   
  37.                 reload = false;   
  38.             }   
  39.         }   
  40.     }   
  41.     return theServlet;   
  42. }  

通过这个类,获得了一个"theServlet"实例作为JSP编译之后的Servlet引用,并且在JSP没有改动前,这个实例是不需要重新生成的。

通过这两个步骤后,最后调用了JSP编译后的Servlet类的#service()方法去处理请求。至此,Tomcat的请求处理结束了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值