这是一个后续的“JSP的开销包括”下面的问题:JSP:包括性能,模块化,备选方案和最佳实践,第96
JSP Performance using jsp:include
在我们的应用程序,开发者'jsp:includes'用于在整个应用程序中重复使用的“common”jsp代码,从而“模块化”jsp片段。
优点
亲的如下:
它DRY--我们曾经定义JSP片段。当您需要更改某些html并且不需要查找/替换/搜索/销毁时,这是一个很大的帮助。
它很容易遵循:你清楚地传递参数。当你编辑'收录'页面时,你'知道你正在收到',也就是'包含/调用'页面中声明的一些'全局变量'。额外的请求
缺点
- 性能开销
问题
所以作为后续:
- 'jsp:include'会产生多少性能开销?从tomcat代码中并不明显(尽管你看到它比内联调用要多得多)。另外在分析应用程序时我从来没有requestDispatcher.include()或invoke()方法显示为热点。
- 有人可以指出在哪里正是谎言的大部分开销? (即类Y中的方法X)或者它是否只是每个请求发生的所有“小东西”(例如,设置属性或对象创建以及随后的GC)?
- 有什么选择? (AFAIK @include和jsp:include。其他什么东西?)
- (愚蠢的奖金问题)为什么在编译时servlet引擎'包含'jsp,即像'带参数的内联宏'一样,这样我们的开发人员可以得到'jsp:include'的清晰度和'@include'的性能。
我一直在想这最后一个问题。我在过去的生活中使用过代码生成工具,从来没有完全理解缺少包含jsp片段的选项。
为了读者的利益,我已经包含了tomcat的'applicationDispatcher.invoke()'方法(tomcat 5.5。抱歉,如果它的日期)。为了清楚起见,我修剪了异常处理。
在此先感谢
将
private void invoke(ServletRequest request, ServletResponse response,
State state) throws IOException, ServletException {
// Checking to see if the context classloader is the current context
// classloader. If it's not, we're saving it, and setting the context
// classloader to the Context classloader
ClassLoader oldCCL = Thread.currentThread().getContextClassLoader();
ClassLoader contextClassLoader = context.getLoader().getClassLoader();
if (oldCCL != contextClassLoader) {
Thread.currentThread().setContextClassLoader(contextClassLoader);
} else {
oldCCL = null;
}
// Initialize local variables we may need
HttpServletResponse hresponse = (HttpServletResponse) response;
Servlet servlet = null;
IOException ioException = null;
ServletException servletException = null;
RuntimeException runtimeException = null;
boolean unavailable = false;
// Check for the servlet being marked unavailable
if (wrapper.isUnavailable()) {
wrapper.getLogger().warn(
sm.getString("applicationDispatcher.isUnavailable",
wrapper.getName()));
long available = wrapper.getAvailable();
if ((available > 0L) && (available < Long.MAX_VALUE))
hresponse.setDateHeader("Retry-After", available);
hresponse.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, sm
.getString("applicationDispatcher.isUnavailable", wrapper
.getName()));
unavailable = true;
}
// Allocate a servlet instance to process this request
try {
if (!unavailable) {
servlet = wrapper.allocate();
}
}
...exception handling here....
// Get the FilterChain Here
ApplicationFilterFactory factory = ApplicationFilterFactory.getInstance();
ApplicationFilterChain filterChain = factory.createFilterChain(request,
wrapper,servlet);
// Call the service() method for the allocated servlet instance
try {
String jspFile = wrapper.getJspFile();
if (jspFile != null)
request.setAttribute(Globals.JSP_FILE_ATTR, jspFile);
else
request.removeAttribute(Globals.JSP_FILE_ATTR);
support.fireInstanceEvent(InstanceEvent.BEFORE_DISPATCH_EVENT,
servlet, request, response);
// for includes/forwards
if ((servlet != null) && (filterChain != null)) {
filterChain.doFilter(request, response);
}
// Servlet Service Method is called by the FilterChain
request.removeAttribute(Globals.JSP_FILE_ATTR);
support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT,
servlet, request, response);
}
...exception handling here....
// Release the filter chain (if any) for this request
try {
if (filterChain != null)
filterChain.release();
}
...exception handling here....
// Deallocate the allocated servlet instance
try {
if (servlet != null) {
wrapper.deallocate(servlet);
}
}
...exception handling here....
// Reset the old context class loader
if (oldCCL != null)
Thread.currentThread().setContextClassLoader(oldCCL);
// Unwrap request/response if needed
// See Bugzilla 30949
unwrapRequest(state);
unwrapResponse(state);
// Rethrow an exception if one was thrown by the invoked servlet
if (ioException != null)
throw ioException;
if (servletException != null)
throw servletException;
if (runtimeException != null)
throw runtimeException;
}
该链接是给404一个替换或许? http://docs.oracle.com/javaee/1.4/tutorial/doc/JSPTags5.html – 2012-07-27 09:13:42