티스토리 뷰

Java/servlet

서블릿

LichKing 2015. 10. 14. 10:22

이클립스에서(굳이 IDE툴이 아니라도) 톰캣(더 정확히는 WAS)을 실행시키면 여러 서버설정 xml파일들이 읽힘.

이것저것 파일들이 있겠지만 사실 개발자에게 가장 중요한 web.xml도 이때 와스가 읽게됨.

 

WAS가 구동되면서 프로젝트에 존재하는 서블릿들도 JVM에 로딩됨.

*클래스가 로딩되는거지 서블릿 객체생성은 아님.

*WAS에 따라서 이때 서블릿 객체를 생성하는 경우도있고 로딩만 해놓고있다가 첫 요청이 들어오면 그때 생성하는 경우도있음

 

WAS가 구동되면서 ServletContext 객체를 생성함. ServletContext 객체는 모든 서블릿이 공유하는 객체임. web.xml에 해당 context 객체에 저장할 파라미터를 정의할 수 있는데 web.xml에서는 기본형변수밖에 정의할 수 없음. 물론 굳이 객체를 여기다가 정의하겠다 하고자하면 직렬화해서 하는 방법이 있긴하지만 이건 편리하게 설정하려는 취지에 부합하지않음.

ServletContext객체에는 처음 초기화할때말고도 중간에 setAttribute()를 할수있기때문에 서블릿상에서 속성 추가가 가능함.

하지만 초기화할때부터 ServletContext에 객체를 담아두고싶은경우가 있을수있는데 이 경우 어떤 서블릿이 가장 먼저 실행될지는 아무도 알 수 없으므로 web.xml에도 정의할 수 없고 서블릿에도 정의할 수 없음.

이런 문제를 해결하기 위한게 리스너임. WAS는 서블릿을 생성하기전에 ServletContext 클래스를 생성하고 리스너 클래스를 생성 한후 내부 메서드를 실행시킴.

이 메서드에서는 이미 생성된 ServletContext 객체를 참조할 수 있기때문에 리스너클래스의 메서드에서 필요한 객체를 생성한 후 참조하고있는 ServletContext 객체에 setAttribute()를 하게되면 그 어떤 서블릿보다 먼저 실행되기때문에 모든 서블릿에서 참조가 가능하다.

 

그리고 서블릿객체들이 생성되는데 이떄 생성되는 객체는 말그대로 일반 객체다. 우리가 서블릿의 라이프사이클을 관리할때 서블릿의 생성자가 아니라 init에 초기화 문구를 넣는 이유가 여기있다.

서블릿의 기본생성자로 서블릿을 생성한 후 ServletConfig 객체를 생성하고 서블릿의 init(ServletConfig) 메서드를 실행하게되는데 ServletConfig 객체는 ServletContext와 달리 해당 서블릿에서만 참조가 가능한 객체다. 이 init을 실행한 후 우리가 재정의하게되는 파라미터가 비어있는 init()을 실행하게된다.

단순히 객체생성만 되어있는 서블릿은 서블릿이라 볼수없는 일반 자바객체일뿐이고 init(ServletConfig) 메서드가 실행되면서 서블릿이 되는것이기때문에 우리가 서블릿초기화를 위해 성급하게 생성자에 소스를 넣는게 아니라 init()에 초기화를 해야하는 것이다.

 

이런 과정을 통해 서블릿이 생성 된 후 요청이 들어오게되면 WAS에서 스레드를 생성해 서블릿의 service() 메서드를 실행시키게된다. 아마 service()에는 요청들어온 HTTP 메서드를 판단해 doGet(), doPost() 를 실행시키는 소스가 들어있을듯하다.

 

요청이 들어올때마다 서블릿 객체를 생성해서 실행하는게 아니라 인스턴스는 1개만 존재하고 스레드를 생성해서 돌리기때문에 메모리효율적에서 CGI보다 좋다고 볼수있다.

스레드는 WAS가 생성해주기때문에 우리가 스레드까지 생각할 필요는 없지만 Thread-safe에 대해서는 생각할 필요가있다. 때문에 서블릿에서는 전역변수는 가급적 사용을 자제하고 최대한 지역변수로 처리해야한다. 전역변수를 굳이 써야한다면 final로 선언하는것이 좋다. 중간에 한 스레드가 값을 바꿔버리면 큰일날 소지가 있기때문이다.

 

여담으로 스프링적인 얘기를 좀 덧붙이자면 사실 지금까지 web.xml에 스프링 사용 설정들을 할때 이걸 왜, 이게 무얼 하는건지 정확히 이해하고 한적은없다. 그냥 <context-param> 이란 태그를 쓰니까 나도 써야지 라는 식이었지 이게 뭔지는 몰랐다. 하지만 WAS의 구동과 서블릿에 대해 좀 공부를 하고나니 dispatcherservlet, contextloaderlistener 등등에 대해 좀더 확실하고 얘가 뭘하는건지 이해가 되는것같다. 자바 웹개발자라면 서블릿에대한 이해를 왜 필수라고하는지 알것같기도 하다.

 

이것이 대략적으로 내가 파악한 서블릿의 실행순서, 원리이다. 사실 전반적인 흐름은 이해하고있다고 생각했는데 이걸 다시 글로 표현하려니 많이 힘들고 내 지식에 자신감이 떨어지는듯 하다. context, config, 서블릿 객체의 실행순서가 좀 틀릴수도 있는데 혹시 틀린부분이 있다면 지적해주시면 감사하겠다.

'Java > servlet' 카테고리의 다른 글

서블릿 보안  (0) 2015.11.05
Servlet Listener Interface  (0) 2015.10.21
서블릿  (0) 2015.10.14
댓글
댓글쓰기 폼