스프링은 서블릿을 발전시킨 것이므로 스프링을 잘 이해하기 위해서는 서블릿에 대한 이해가 필요하다.
1. 서블릿(Servlet)과 Controller의 차이
Servlet과 Controller의 선언부를 보면서 둘의 차이를 알아보겠다.
1) Servlet
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
@Override
public void init() throws ServletException {
- HttpServlet을 상속받는다.
- 매개변수로 request와 response를 반드시 포함해야 한다.
- URL mapping을 클래스 단위로 한다.
2) Controller
@Controller
public class LoginController {
@RequestMapping("/login")
public String loginForm() {
- 상속이 없다.
- 자바는 단일 상속이기 때문에 최대한 상속을 받지 않는 것이 유리함
- 매개변수를 반드시 필요로 하지 않는다.
- URL Mapping을 메서드 단위로 한다.
- 하나의 클래스 안에서 또다른 Mapping이 가능함
Controller는 Servlet을 더 발전시킨 형태임을 알 수 있다.
2. Servlet의 구조
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
@Override
public void init() throws ServletException {
// 서블릿 초기화 - 서블릿이 생성 또는 리로딩 때, 단 한번만 수행됨.
System.out.println("[HelloSerlvet] init()");
}
@Override // 호출될 때마다 반복적으로 수행됨.
public void service(HttpServletRequest request, HttpServletResponse response) {
// 1. 입력
// 2. 처리
// 3. 출력
System.out.println("[HelloSerlvet] service()");
}
@Override
public void destroy() {
// 뒷정리 작업 - 서블릿이 제거(unload)될 때, 단 한번만 수행됨.
System.out.println("[HelloSerlvet] destroy()");
}
}
- init()
- 서블릿 초기화 - 서블릿이 생성 또는 리로딩 할때 수행된다.
- service
- 호출될 때마다 반복적으로 수행된다.
- 실제 작업을 수행한다.
- destroy
- 뒷정리 작업 - 서블릿이 제거될 때, 단 한번만 수행된다.
3. 서블릿의 생명 주기
서블릿은 싱글톤(Singleton)패턴으로 만들어진다.
- 한 개의 인스턴스를 생성 후 재활용함
1. 클라이언트로부터 요청이 들어옴
2. Servlet 인스턴스가 존재하는지 확인
3 - (1). 인스턴스가 없는 경우
- Servlet 인스턴스를 생성함
- 만들어진 인스턴스를 초기화함
- 서비스 호출
3 - (2) 인스턴스가 있는 경우
- 서비스 호출
4. 결과를 반환함
프로그램이 종료될 시 destroy()를 호출하여 인스턴스를 삭제함.
4. JSP(Java Server Page)
HTML에 Java 코드를 추가한 형태다.
- <%! ... %>는 클래스 영역으로 변환됨
- <% ... %>는 메서드 영역으로 변환됨
- html부분은 out.println()으로 변환됨
JSP 예시
<%@ page contentType="text/html;charset=utf-8"%>
<%@ page import="java.util.Random" %>
<%-- <%! 클래스 영역 %> --%>
<%!
int getRandomInt(int range){
return new Random().nextInt(range)+1;
}
%>
<%-- <% 메서드 영역 - service()의 내부 %> --%>
<%
int idx1 = getRandomInt(6);
int idx2 = getRandomInt(6);
%>
<html>
<head>
<title>twoDice.jsp</title>
</head>
<body>
<img src='resources/img/dice<%=idx1%>.jpg'>
<img src='resources/img/dice<%=idx2%>.jpg'>
</body>
</html>
변환된 Servlet 예시
@WebServlet("/rollDice2")
public class TwoDiceServlet extends HttpServlet {
int getRandomInt(int range) {
return new Random().nextInt(range)+1;
}
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
int idx1 = getRandomInt(6);
int idx2 = getRandomInt(6);
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("</head>");
out.println("<body>");
out.println("<img src='resources/img/dice"+idx1+".jpg'>");
out.println("<img src='resources/img/dice"+idx2+".jpg'>");
out.println("</body>");
out.println("</html>");
out.close();
}
}
5. JSP 호출 과정
1. jsp 요청이 들어옴
2 - (1). Servlet 인스턴스가 존재하지 않음
- JSP 파일 변환
- JSP 파일 컴파일
- Sevlet 인스턴스 생성
- Servlet 인스턴스 호출
2 - (2). Servlet 인스턴스가 존재함
- Servlet 인스턴스 호출
3. 결과 반환
6.늦은 초기화(Lazy-init)와 빠른 초기화(Early-init)
객체가 생성되고 초기화하는 과정이 언제 이루어지는 지에 따라 늦은 초기화와 빠른 초기화로 나눌 수 있다.
1) 늦은 초기화(Lazy-init)
- 클라이언트로부터 요청이 들어올 때 객체를 생성함
- Servlet의 경우
2) 빠른 초기화(Early-init)
- 클라이언트에게 요청이 오기 전에 객체를 생성해둠
- 스프링의 경우
Servlet의 경우 늦은 초기화를 사용하기 때문에 인스턴스를 처음 호출했을 때와 두번째로 호출했을 때 응답 속도가 다르다. 첫번째 호출의 경우 인스턴스를 생성하는 데 시간이 필요하기 때문이다.
총평
아 재밌다.
'🍃Spring ,SpringBoot 공부 > 스프링의 정석 : 남궁성과 끝까지 간다' 카테고리의 다른 글
[스프링] @RequestParam과 @ModelAttribute (0) | 2022.11.25 |
---|---|
[Spring공부/스프링의 정석] 서블릿(Servlet)과 JSP - 2 (0) | 2022.11.18 |
[Spring 공부/스프링의 정석] 관심사의 분리와 MVC 패턴 (0) | 2022.11.02 |
댓글