首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

WebLogic Server-避免用不着的JSP重新编译

2012-09-20 
WebLogic Server-避免不必要的JSP重新编译摘要  关于JavaServer页面(JSP)新闻组的最常见的一个问题与重新

WebLogic Server-避免不必要的JSP重新编译
摘要
  关于JavaServer页面(JSP)新闻组的最常见的一个问题与重新编译有关。不想重新编译JSP,却又不得不这样做,这是许多开发人员所面对的烦恼。本文将描述造成重新编译的场景,并从解释WebLogic JSP容器的内部操作开始,介绍每个显然“不受欢迎的”场景,并应用容器的过期检查算法(Stale Checking Algorithm)。此外,本文还将讨论控制JSP和servlet类重载的参数。对以生产模式下运行的服务器,极力推荐这么做。

JSP容器的过期检查机制
  在WebLogic中,JSP被编译成.class文件。我们使用的术语过期检查机制(Stale Checking Mechanism)指的是用来判断某一特殊JSP .class文件是否比当前JSP文件更旧(“过期”)的逻辑。WebLogic JSP容器确保任何JSP及其相关文件只在修改后才能被重新编译。查看生成的Java代码是了解JSP容器内部操作的一个好方法。我们将采用一个JSP作为例子,使用命令行JSP编译器编译它,并查看生成的源代码。JSP编译器(WebLogic.jspc)是随标准WebLogic 服务器安装工具箱一起提供的。

考虑一个称为foo.jsp的简单JSP页面:

A simple JSP page

  现在使用命令行JSP编译器来编译这个JSP,指定一个称为keepgenerated的选项,顾名思义,该选项为JSP页面生成相应的Java代码,并将代码保存在磁盘上。

java weblogic.jspc -keepgenerated -d .WEB-INFclasses foo.jsp[jspc]warning: expected file /WEB-INF/web.xml not found,tag libraries cannot be resolved.<Jul 11, 2004 7:29:26 PM PDT> <Warning> <HTTP> <BEA-101181> <Could not find web. xml under WEB-INF in the doc root: ..>

  编译器在作为上述选项指定的输出目录(-d)中生成.java文件及其对应的.class文件。它将生成的类文件放在称为jsp_servlet的包中,这恰巧是默认的JSP包前缀(除非在weblogic.xml中覆盖),因此,生成的Java文件可在.WEB-INFclassesjsp_servlet中找到,并且称为__foo.java。
  请注意,我们可忽略编译器发出的关于未找到web.xml文件的警告,因为此时我们并没有真正使用标签库。
  在生成代码(__foo.java)中,与我们的讨论最相关的部份就是staticIsStale()方法,如下所示。

清单1. staticIsStale()方法

<!DOCTYPE weblogic-web-app PUBLIC "-//BEA Systems, Inc.//DTD Web Application 8.1//EN" "http://www.bea.com/servers/wls810/dtd/weblogic810-web-jar.dtd"><weblogic-web-app>    <container-descriptor>         <servlet-reload-check-secs>-1</servlet-reload-check-secs>     </container-descriptor></weblogic-web-app>

JSP类加载器
  我们将通过查看WebLogic服务器如何加载JSP类来结束我们的讨论。每个JSP都是在自己的类加载器(通常称为一次性类加载器)中加载的。该类加载器是Web应用程序类加载器的子加载器,负责加载有关的JSP类及其内部类(如果有的话)。好奇的读者可能会觉得奇怪,为什么WebLogic在每个JSP自己的类加载器中加载JSP。真的需要这么复杂吗?WebLogic不能只用应用程序类加载器而使得生活更轻松吗?所有这些问题都是有根据的,而且每个寻求WebLogic类加载器天堂的人都应该问自己这些问题。为了解决这些问题,让我们设想我们的Web应用程序有几个JSP、少数servlet、一个过滤器以及几百个还包含标签处理器类的实用类。现在,假设所有这些类都被加载到单个类加载器中。如果修改单个JSP,然后单击浏览器上的重载,那么下面的事情将不得不发生:

  • JSP容器将不得不重新编译页面。
  • 将不得不丢弃用来加载较早类版本的整个Web应用程序类加载器。
  • 不得不创建一个新的Web应用程序类加载器,而且要重载和重新初始化所有servlet和JSP(包括刚才修改的那个)。

      Java不允许重用类加载器来重载类的新版本。相反,您不得不放弃类加载器并创建一个新的。基于这个原因,上面的场景非常不合时宜;即使只更改了一个类,应用服务器也不得不重载大量的类。
      现在,让我们看看WebLogic是如何实现其类加载器方案的。考虑一下前面提及的那个场景。如果我们修改JSP,并碰巧在浏览器上进行重载,那么服务器将执行以下任务:

    • JSP容器重新编译页面。
    • 它丢弃用来加载这个JSP类的旧版本的那个JSP类加载器。
    • 它创建一个将Web应用程序类加载器作为父加载器的新JSP类加载器,并为该页面提供服务。

        如您所见,只有一个JSP类必须重载,整个Web应用程序类加载器保持不动,并且不受我们对JSP所做小小改动的影响。因此,在修改单个JSP时,容器会丢弃旧的类加载器、重新编译并只重载为这个JSP生成的类。这避免了重载或抛弃整个Web应用程序类加载器。当只有某一特殊Web应用程序中的某些JSP经常改变时,这是一个很大的胜利。

      结束语
        有了这些关于JSP容器内部组织的知识,不但可以避免遭遇令人不快的、不必要的JSP重新编译的状况,而且还可以通过使用pageCheckSeconds和servlet-reload-checks-secs参数改进页面响应时间自身。
        Nagesh Susarla是BEA Systems的WebLogic服务器开发小组的一名高级软件工程师。他致力于为WebLogic服务器设计和实现Servlet/JSP容器,而且还是ANTLR (分析器/生成器)的超级爱好者。

      原文出处:
      http://dev2dev.bea.com/pub/a/2005/01/jsp_reloaded.html

热点排行