문득 Jsp는 수정시 왜 서버 리로딩 없이 동작할 수 있는지에 대해서 궁금해져 정리해 보았다.
기본적으로 자바소스를 컴파일하여 class로 바꾸고 jvm이 바이트 코드를 읽어 처리하려면 컴파일 과정이 필요하다.
Jsp는 자바소스로 동작하는데 어떻게 컴파일 과정 없이 실행될 수 있을까?
Jsp의 동작 과정은 다음과 같다.
1. 사용자가 웹 브라우저에서 jsp요청
2. 웹 컨테이너(tomcat)이 jsp를 읽고 서블릿 코드로 변환
3. 변환된 서블릿 코드는 .java 파일로 생성
4. .java 파일이 자동으로 컴파일 후 .class 생성
5. 생성된 .class 파일(서블릿 클래스)를 실행하여 결과를 사용자에게 반환
이렇게 웹컨테이너에 의해 자동으로 컴파일이 실행된다.
스프링 기반으로 동작하는 java파일들이 빌드시 컴파일 되는 과정과 컴파일 시기가 다르다.
그렇다면 서블릿에 대해서 자세히 알아보자.
웹 컨테이너에서 생성된 서블릿 코드는 어떻게 생겼을까?
- jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>JSP to Servlet</title>
</head>
<body>
<h1>Hello, JSP!</h1>
<p>Current Time: <%= new java.util.Date() %></p>
</body>
</html>
- servlet
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.util.*;
public final class example_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();
private static java.util.List<String> _jspx_dependants;
public java.util.List<String> getDependants() {
return _jspx_dependants;
}
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, ServletException {
PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Object page = this;
JspWriter _jspx_out = null;
PageContext _jspx_page_context = null;
try {
response.setContentType("text/html; charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("<!DOCTYPE html>\n");
out.write("<html>\n");
out.write("<head>\n");
out.write(" <title>JSP to Servlet</title>\n");
out.write("</head>\n");
out.write("<body>\n");
out.write(" <h1>Hello, JSP!</h1>\n");
out.write(" <p>Current Time: ");
out.write(String.valueOf(new java.util.Date()));
out.write("</p>\n");
out.write("</body>\n");
out.write("</html>\n");
} catch (Throwable t) {
if (!(t instanceof SkipPageException)) {
out = _jspx_out;
if (out != null && out.getBufferSize() != 0) out.clearBuffer();
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
여기서 또 궁금한점은 항상 컴파일을 수행하면 느릴거 같다.
빌드시 컴파일 하는 과정을 통상적으로 보면 느리기 때문이다.
그럼 서블릿은 어떻게 빠른 속도를 유지할 수 있는걸까?
답은 캐싱에 있다.
모든 시스템에서 하는 것처럼 최초 요청시 한 번만 컴파일 후 이후에는 존재하는 .class파일을 바로 사용하고
jsp가 변경될시에는 변경감지로 재컴파일하는 과정을 겪는다.
- 결론 : jsp도 똑같이 컴파일 과정을 겪는다. 그 컴파일 과정은 웹 컨테이너에서 일어난다. 항상 컴파일 하지 않고 캐싱을 수행하기 때문에 항상 느린 속도로 응답하지 않는다.
'백엔드 > JAVA' 카테고리의 다른 글
Stream (0) | 2023.08.15 |
---|---|
BigInteger 클래스 (0) | 2023.01.17 |
생성자, 상속, 접근자 (0) | 2022.04.22 |
replaceAll, 문자열 정규식 (0) | 2022.04.19 |
Collector.sort(), Compareto() (0) | 2022.04.04 |
댓글