当前位置: 代码迷 >> JavaScript >> tomcat之是不是编译JSP的条件
  详细解决方案

tomcat之是不是编译JSP的条件

热度:191   发布时间:2013-10-29 12:07:57.0
tomcat之是否编译JSP的条件
我们在开发的过程中,修改JSP的内容后,不启动容器的情况下,可以进行应用,这是为什么呢? 容器到底做了什么呢? 它怎么知道我们的JSP有变化呢? 哈哈,接下来我们就来揭开TOMCAT的这层面纱:
1.我们在访问JSP面的的时候执行的流程为:
  容器启动后,会有一个无限循环的等待来接由客户端的请求,这个是由JIoEndpoint.Acceptor线程来完成的,代码如下:
protected class Acceptor implements Runnable {


        /**
         * The background thread that listens for incoming TCP/IP connections and
         * hands them off to an appropriate processor.
         */
        public void run() {

            // Loop until we receive a shutdown command
            while (running) {

                // Loop if endpoint is paused
                while (paused) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // Ignore
                    }
                }

                // Accept the next incoming connection from the server socket
                try {
                    Socket socket = serverSocketFactory.acceptSocket(serverSocket);
                    serverSocketFactory.initSocket(socket);
                    // Hand this socket off to an appropriate processor
                    if (!processSocket(socket)) {
                        // Close socket right away
                        try {
                            socket.close();
                        } catch (IOException e) {
                            // Ignore
                        }
                    }
                }catch ( IOException x ) {
                    if ( running ) log.error(sm.getString("endpoint.accept.fail"), x);
                } catch (Throwable t) {
                    log.error(sm.getString("endpoint.accept.fail"), t);
                }

                // The processor will recycle itself when it finishes

            }

        }

    }
2.当容器收到一个请求后,CoyoteAdapter类的service方法来处理 ,然后通过责任链模式调用到StandardWrapperValve.java类invoke方法中调用ApplicationFilterChain类的doFilter  接着来到HttpServlet的Service方法中 调用JspServlet.java类的service方法中,serviceJspFile 。。。JspServletWrapper.java类的service方法中, if (options.getDevelopment() || firstTime ) {
                synchronized (this) {
                    firstTime = false;

                    // The following sets reload to true, if necessary
                    ctxt.compile();
                }
            } else {
                if (compileException != null) {
                    // Throw cached compilation exception
                    throw compileException;
                }
            }
最后来到,JspCompilationContext.java类的compile方法中,重点来了,
public void compile() throws JasperException, FileNotFoundException {
        createCompiler();
        [b]if (jspCompiler.isOutDated()) {[/b]
            try {
                jspCompiler.removeGeneratedFiles();
                jspLoader = null;
                jspCompiler.compile();
                jsw.setReload(true);
                jsw.setCompilationException(null);
            } catch (JasperException ex) {
                // Cache compilation exception
                jsw.setCompilationException(ex);
                throw ex;
            } catch (Exception ex) {
                JasperException je = new JasperException(
                            Localizer.getMessage("jsp.error.unable.compile"),
                            ex);
                // Cache compilation exception
                jsw.setCompilationException(je);
                throw je;
            }
        }
    }
以上加粗的地方来判断是否进行重新编译JSP页面,
public boolean isOutDated(boolean checkClass) {

        String jsp = ctxt.getJspFile();

        if (jsw != null
                && (ctxt.getOptions().getModificationTestInterval() > 0)) {

            if (jsw.getLastModificationTest()
                    + (ctxt.getOptions().getModificationTestInterval() * 1000) > System
                    .currentTimeMillis()) {
                return false;
            } else {
                jsw.setLastModificationTest(System.currentTimeMillis());
            }
        }

        long jspRealLastModified = 0;
        try {
            URL jspUrl = ctxt.getResource(jsp);
            if (jspUrl == null) {
                ctxt.incrementRemoved();
                return false;
            }
            URLConnection uc = jspUrl.openConnection();
            if (uc instanceof JarURLConnection) {
                jspRealLastModified =
                    ((JarURLConnection) uc).getJarEntry().getTime();
            } else {
                jspRealLastModified = uc.getLastModified();
            }
            uc.getInputStream().close();
        } catch (Exception e) {
            return true;
        }

        long targetLastModified = 0;
        File targetFile;

        if (checkClass) {
            targetFile = new File(ctxt.getClassFileName());
        } else {
            targetFile = new File(ctxt.getServletJavaFileName());
        }

        if (!targetFile.exists()) {
            return true;
        }

        targetLastModified = targetFile.lastModified();
        if (checkClass && jsw != null) {
            jsw.setServletClassLastModifiedTime(targetLastModified);
        }
        if (targetLastModified < jspRealLastModified) {
            if (log.isDebugEnabled()) {
                log.debug("Compiler: outdated: " + targetFile + " "
                        + targetLastModified);
            }
            return true;
        }

        // determine if source dependent files (e.g. includes using include
        // directives) have been changed.
        if (jsw == null) {
            return false;
        }

        List depends = jsw.getDependants();
        if (depends == null) {
            return false;
        }

        Iterator it = depends.iterator();
        while (it.hasNext()) {
            String include = (String) it.next();
            try {
                URL includeUrl = ctxt.getResource(include);
                if (includeUrl == null) {
                    return true;
                }

                URLConnection iuc = includeUrl.openConnection();
                long includeLastModified = 0;
                if (iuc instanceof JarURLConnection) {
                    includeLastModified =
                        ((JarURLConnection) iuc).getJarEntry().getTime();
                } else {
                    includeLastModified = iuc.getLastModified();
                }
                iuc.getInputStream().close();

                if (includeLastModified > targetLastModified) {
                    return true;
                }
            } catch (Exception e) {
                return true;
            }
        }

        return false;

    }
  相关解决方案