웹 애플리케이션 구조, Servlet Container 와 라이프 사이클(Life Cycle)

Yeppi's 개발 일기·2022년 5월 25일
0

Servlet&JSP

목록 보기
4/13
post-thumbnail
post-custom-banner

1. 웹 애플리케이션 구조

1) 웹 프로젝트 패키징

디렉토리 구조 확인을 위한 작업

  • 실제 운영 서버에 배포할 수 있는 WAR(Web Archive) 파일로 패키징 작업

  • 서버 사이의 이식성을 보장하기 위해
    → 웹 애플리케이션은 모든 서버가 인식하는 정형화된 디렉토리 구조를 유지해야 함
    👉 웹 프로젝트 패키징이 하는 일



2) 웹 애플리케이션 디렉토리

war 파일 구조

해당 프로젝트의 war 압축 파일을 반디집으로 열어보았다

이클립스가 알아서 만들어 주기 때문에, 아래 것들만 기억하자

  • src/main/javajava 파일 작성하기 → 자동으로 classes 에 넣어줌

  • libjar 파일 넣기

  • webapp에 자바파일 외 모든 파일 작성하기


  • 브라우저는 WEB-INF 폴더안에 파일을 못찾음 → 여기 안에 파일 만들지말기
  • WEB-INF 는 꼭 있어야 됨
    • 중요한 폴더는 WEB_INF 폴더 안에 감춤
    • 브라우저에서 요청할 수 없는 특수한 디렉토리
  • META-INF 는 없어도 상관없음
  • 모든 파일은 고유의 위치가 있음
    • 웹 애플리케이션 루트에 파일 생성하기!
  • 압축파일
    • 자바 아카이브 → 자르 .jar
      • 클래스만
    • 웹 아카이브 → 와르 .war
      • html, 이미지, 클래스들

🧐 프로젝트 이름이 웹 어플리케이션 루트 이름과 같다. 따라서 서버에는 WAR 파일이 올라가 있다 🧐



war 파일 생성

  • export
  • 오른쪽 브라우저 버튼누르고 패키지와 같은 경로(BoardWeb)에 실행
  • 새로 고침(F5) 하면 생성


2. Servlet Container

1) 톰캣 서버

  • 톰캣 서버가 내부적으로 서블릿 컨테이너를 구동하여 사용함
  • 서블릿 컨테이너는 web.xml 파일에 등록된 서블릿 클래스의 객체를 생성 및 관리

정적 컨텐츠

  • 웹은 95프로가 정적
  • 웹 서버에서 바로 처리 👉 응답 속도 빠름

동적 컨텐츠

  • 서블릿 컨테이너에게 forwarding(넘김)
  • 웹 서버에서 처리할 수 없음


2) 서블릿 컨테이너

컨테이너

객체의 저장소

  • 특정 목적을 위해 관련된 객체 생성
  • 효율적 + 안전하게 관리하기 위해 사용
  • 컨테이너 안에는 Map 과 같은 컬렉션과 매우 유사 → key value
    • key 값은 unique 해야함(파란색)

web.xml

서블릿 컨테이너가 어떤 객체를 저장하고 어떻게 관리할 지에 대한 명세

  • 기본 값은 WEB-INF 폴더에 있는 web.xml 파일을 로딩


3. Servlet 규칙

  1. servlet과 javax.servlet.http 패키지의 API를 import
  2. public 클래스로 선언
  3. HttpServlet 클래스를 상속
  4. 반드시 기본 생성자를 가져야 함
  5. 라이프 사이클과 관련된 메소드를 오버라이딩

1번은 이클립스가 알아서 해줌
2번은 public 이어야 함
3번은 이클립스가 알아서 해줌
4번은 반드시 디폴트 생성자만 있어야함, 매개변수를 받는 생성자는 사용 불가
5번은 오버라이딩한 메서드여야 하므로, 메소드 시그니처(리턴타입, 이름, 매개변수)는 수정 불가



4. Servlet 계층 구조

HttpServlet 을 상속하여 서블릿 클래스를 작성

Servlet > GenericServlet > HttpServlet > LoginServlet

  • 서블릿 클래스 객체 생성 및 관리 시,
    최상위 인터페이스인 Servlet 타입으로 묵시적 형변환
  • MAP 에 등록 되는 순간,
    부모타입인 Servlet 타입으로 묵시적 형변환
  • 콜백 메서드
    특정 시점에 서블릿 컨테이너가 자동으로 호출하는 서블릿 객체의 메서드

HttpServlet 상속

  • LoginServlet 객체는 Servlet 타입으로 cast(형변환) 할 수 없음
    👉 emplements HttpServlet 를 상속 받아야
    Servlet 타입으로 형변환하고, 브라우저가 요청할 때 아래 오류가 안뜸


5. Servlet 객체와 라이프사이클

1) 서블릿 객체 생성

레이지 로딩(Lazy-Loading)

브라우저가 요청을 했을 때(url 입력)
클라이언트(브라우저)가 요청하기 전까지 객체생성을 미루고 있다가 생성하는 것

  • web.xml 파일에 등록된 서블릿 클래스 객체
    브라우저가 서버에 요청을 전달할 때 생성되는 것
  • 브라우저의 요청에 대해서 반응 속도는 느림
  • 요청할 때 생성하므로 → 서버 메모리를 효율적 사용

프리 로딩(Pre-Loading)

브라우저의 요청을 하든말든 상관 없이
서블릿 컨테이너가 XML 파일을 읽자마자, 등록된 게 있으면 무조건 생성

  • 사용자의 요청과 무관하게
    컨테이너가 구동되는 시점에 XML 설정 파일에 등록된 객체를 생성하는 것
  • 반응 속도는 빠름
  • 사용하지 않는 객체를 미리 생성 → 비효율적

Singleton

  • 서블릿 컨테이너는 web.xml 파일에 등록된 서블릿 클래스로부터 단 하나의 객체만 생성
  • 다른 브라우저여도 메모리는, 객체는 단 하나만 뜸
  • 메모리에 단 하나의 서블릿 객체는 최초의 요청 했을 때 만들어짐


3) 서블릿 생성과 실행(Life Cycle)

  • Pool
    객체들이 모아져있는 컬렉션
    ex. arraylist, hashset, hashmap 등
  • Thread 객체는 Thread 클래스에서 자동으로 생성
    Thread 클래스는 Servlet Container에서 자동으로 만들어줌

실행 과정

1.request

  • 브라우저가 로그인 프로세서가 요청

  • Web Server는 정적 콘텐츠만 처리 가능

2.forwarding

  • Servlet Container에게 정적 콘텐츠 처리 해달라고 넘김

3. 메모리있나?

  • 로그인 프로세스에 대한 요청에 대해서
    이름이 login인 LoginServlet의 객체가 메모리에 있나 없나?

👉 최초의 요청이면 없다

메모리에 없을 때

4.class 메모리 로딩

  • 없으면, login.clss 파일을 메모리에 로딩

  • 서블릿 컨테이너가 classes 디렉토리 폴더를 뒤져서 찾아봄

5.디폴트 생성자()

  • 로딩되자마자 서블릿 컨테이너가 디폴트 생성자를 호출
    (서블릿 컨테이너는 서블릿 객체 생성할 때 디폴트 생성자만 호출할 수 있다)

  • 이제 객체가 메모리에 올라감

6. init()

  • 객체 생성 직후에 서블릿 컨테이너가 딱한번 init() 메소드를 호출

  • init() 메소드가 오버라이딩 되어있으면?
    컨테이너가 특정 시점에 자동으로 호출해주는 메소드 = 콜백메소드

  • init() 메소드의 용도
    멤버변수를 초기화 가능


메모리에 있을 때

Thread

  • 컨테이너는 Thread Pool에서 Thread하나를 꺼내고
    Service()를 하나 호출

Service()

  • 요청방식이 GET이면 doGet() 호출
    요청방식이 POST면 doPost() 호출

  • 만약, service()를 오버라이딩하면,
    위의 분기처리하는 service() 가 동작하지 않음

👉 따라서 요청방식이 무엇인 지는 상관없음 무조건 실행!

👉 두 번째 요청부터는 ? 메모리가 있기(YES) 때문에 새로운 Thread 가 계속 호출된다



4) 서블릿 콜백 메서드

컨테이너가 적절한 시험에 알아서 잘 실행시켜주는 것

메소드호출 시점기능
init()서블릿 객체가 생성된 직후멤버 변수 초기화
service()브라우저가 요청할 때마다서블릿이 처리해야할 구체적인 작업처리
destroy()서블릿 객체가 삭제되기 직전자원 해제
  • init() 진짜 거의 안씀
  • destroyy() 안씀


6. @Annotation 설정

  • @WebServlet("/loginProcess") 을 XML 설정 대신 사용

  • 기능은 똑같이 동작함

  • XML 파일에는 아래 부분을 주석처리

    	<servlet>
    		<servlet-name>login</servlet-name>
    		<servlet-class>com.ssamz.web.user.LoginServlet</servlet-class>
    	</servlet>
    	
    	<servlet-mapping>
    		<servlet-name>login</servlet-name>
    		<url-pattern>/loginProcess</url-pattern>
    	</servlet-mapping>

서블릿은 현재 현업에서 잘 사용하지 않지만,
웹 서버와 브라우저의 동작을 보다 잘 이해 할 수 있는 기회가 된다.
추후에 사용할 Spring을 위해 동작 원리를 이해하고, 개발자가 코드로 어떻게 풀어나가야 하는 지에 대해 곰곰히 생각해보며 공부했다

profile
imaginative and free developer. 백엔드 / UX / DATA / 기획에 관심있지만 고양이는 없는 예비 개발자👋
post-custom-banner

0개의 댓글