Dolphins의 HelloWorld

서블릿 라이프사이클 본문

웹 프로그래밍/웹 프로그래밍 기초

서블릿 라이프사이클

돌핀's 2018. 8. 13. 14:09

서블릿의 라이프사이클을 이해하기 위한 간단한 실습을 해보자.


LifecycleServlet이라는 이름을 가진 서블릿을 생성할 것이고


HttpServlet의 3가지 메소드를 오버라이딩 할 것이다.


- init() 


- service(request, response)


- destroy()




메소드가 호출이 되면 콘솔에 print가 되도록 다음과 같이 코드를 작성해보고 실행해보겠다.


package examples;

import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/LifeCycleServlet")
public class LifeCycleServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public LifeCycleServlet() {
        System.out.println("LifecycleServlet 생성!!");
    }

	public void init(ServletConfig config) throws ServletException {
		System.out.println("init 호출!!");
	}

	public void destroy() {
		System.out.println("destroy 호출!!");
	}

	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("service 호출!!");
	}

}



콘솔에 print된 결과를 보면 생성자, init, service 메소드가 호출됐음을 알 수 있다.


그리고 새로고침을 통해 한번더 실행해보면 



다음과 같이 생성자와 init은 다시 실행되지 않고 service메소드만 다시 실행됐음을 알 수 있다.


여기서 다음과 같이 init메소드에 있는 print문을 조금 바꾸고 저장했더니



다음과 같이 destroy 메소드가 호출됐음을 볼 수 있다.


왜 이런 결과가 나타나는 것인지 한번 살펴보자.


먼제 Servlet의 생명 주기를 도식화해보면 다음과 같다.


 처음에 WAS가 서블릿 요청을 받으면 해당 서블릿이 메모리에 있는지 확인한다.


if(메모리에 없음) {

 

 - 해당 서블릿 클래스를 메모리에 올린다.


 - init() 메소드를 실행한다. 

}


 - service()메소드를 실행한다.


그 다음 해당 서블릿이 메모리에 있냐없냐에 따라 위의 알고리즘의 형태로 동작한다.


메모리에 없을 때에만 init()메소드를 실행하기 때문에 처음에는 생성자 init()이 호출됐고


그 다음에는 메모리에 이미 적재된 상태이기 때문에 생성자, init()호출 없이


service만 호출된것이다.



destroy 같은 경우 WAS가 종료되거나 웹 어플리케이션이 새롭게 경신될 경우 실행된다.


위에 있는 예에서 메소드 내용을 바꾼후 갱신을 해주었기 떄문에 destory가 실행된 것이다.



service(request, response) 메소드


실제로 Servlet을 작성할 때 service메소드가 없이도 doGet() 메소드를 통해 서블릿이 잘 실행되는


모습을 볼 수 있다. 


그 이유는 service() 메서드는 실제 HttpServlet의 service()라는 메서드가 구현되어있는 상태이기  

떄문이다.


만약 나에게 service()가 없다면 부모인 HttpServlet의 service() 메서드가 실행이 되는것이다.


이 때 service() 메서드는 클라이언트의 요청이 GET인 경우에는 자신이 가지고 있는


doGet(request, reponse)메서드를 호출하며


클라이언트의 요청이 Post인 경우 자신이 가지고 있는 doPost(request, response)를 호출한다.





기존의 service를 주석처리 한 후 doGet과 doPost를 오버라이딩하여 실습을 한번 해보자.


다음과 같은 코드를 실행해보면


package examples;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/LifeCycleServlet")
public class LifeCycleServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public LifeCycleServlet() {
        System.out.println("LifecycleServlet 생성!!");
    }

	public void init(ServletConfig config) throws ServletException {
		System.out.println("수정된 init 호출!!");
	}

	public void destroy() {
		System.out.println("destroy 호출!!");
	}

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		out.println("<html>");
		out.println("form");
		out.println("");
		out.println("
"); out.println("name :
"); out.println("
"); out.println("</html>"); out.close(); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String name = request.getParameter("name"); out.println("

hello"+name+"

"); out.close(); } //protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // System.out.println("service 호출!!"); //} }




다음과 같이 화면이 나오며 소스보기를 하면 doGet에 작성된 소스가 나옴을 볼 수 있다.


그 이유는 URL에서 직접 요청이 들어왔을 떄는 GET이라는 요청이 들어왔기 때문이다.


그리고 name의 빈칸을 채운후 엔터버튼을 누르면


<form method = 'post'> 이기 때문에


아래와 같이 doPost의 메소드가 실행되는 것을 확인할 수 있다.




출처 : edwith

https://www.edwith.org/boostcourse-web/lecture/16688/

'웹 프로그래밍 > 웹 프로그래밍 기초' 카테고리의 다른 글

JSP 문법  (0) 2018.08.23
Request, Reponse 객체 이해하기  (0) 2018.08.13
Servlet 작성방법 2 (3.0 spec 미만)  (0) 2018.08.13
Servlet 작성방법 1 (3.0 spec 이상에서)  (0) 2018.08.13
Servlet 이란?  (0) 2018.08.13
Comments