[Spring Boot] 스프링부트 원리 - 내장 서버 (컨테이너와 포트)

dsunni·2020년 7월 30일
5

참고

https://scshim.tistory.com/28


스프링 부트의 특징 중 하나는 톰캣 서버가 내장되어있다는 것이다. 내장 서버는 어떻게 작동되는 것일까?

톰캣 내장 서버가 자동 설정의 일부이기 때문이다. 스프링 부트에서는 톰캣과 서블릿 서버가 자동으로 설정되어있다.

따라서 스프링부트 애플리케이션을 실행하면 톰캣이 생성되고 서블릿이 추가가 되면서 애플리케이션이 정상적으로 작동한다.


1. 스프링 부트 자동 설정 (내장 서버)

image

auto configurer의 spring.factories에 자동설정 파일들이 있다.


org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\

ServletWebServerFactoryAutoConfiguration

  • 서블릿 웹 서버 생성 설정 파일

  • TomcatServletWebServerFactoryCustomizer

    • 서버 커스터마이징

DispatcherServletAutoConfiguration

  • Dispatcher 서블릿 만들고 등록 설정 파일


2. 내장 서블릿 컨테이너 응용

서블릿

서블릿이란 javax.servlet package에 정의된 인터페이스이다.

클라이언트의 요청을 처리하고 그 결과를 다시 클라이언트에게 응답하는 Servlet 클래스의 구현 규칙을 지킨 자바 프로그램이다.

서블릿 Life Cycle을 위한 세 가지 메소드를 정의한다.

  • init() - 초기화
  • service() - 요청
  • destroy() - 파괴

서블릿 컨테이너

img

서블릿 컨테이너란 서블릿들을 위한 상자(Container)이다. 클라이언트의 Request를 받아주고 Response를 보내준며 정적인 웹 페이지 생성을 위해 존재한다. 서블릿의 생명 주기를 관리(생성, 초기화, 전달)해준다.

다른 말로는 웹 컨테이너, 웹 애플리케이션 서버(WAS)라고도 불리며 대표적인 Servlet Container는 Tomcat이다.

Servlet 기반 웹 MVC 프로젝트를 개발할 때 자동 설정 파일로 인해 기본적으로 Tomcat을 사용한다.

만약 다른 서블릿 컨테이너를 사용하고자 하면 어떻게 해야할까?


(1) Tomcat이 아닌 다른 서블릿 컨테이너로 변경하기

image

위와 같이 spring-boot-starter-web이 tomcat을 가져오는 것을 볼 수 있다. 따라서 다른 블릿 컨테이너로 변경하고자 하면 우선 이 dependency를 빼야한다.


tomcat dependency 빼기

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

jetty dependency 추가

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>

image

위와 같이 tomcat이 사라지고 jetty가 들어온 것을 확인할 수 있다.



(2) 웹 서버 사용하지 않기 - properties 사용

application.properties

spring.main.web-application-type=none
server.port=7070
  • 웹 서블릿 컨테이너 의존성이 Classpath에 있다 하더라도 무시하고 non-web-application으로 실행한다.
  • 7070 포트로 변경도 가능하다

random port 사용하기

server.port=0
  • Random으로 사용 가능한 포트를 찾아서 포트를 띄워준다.


(3) ApplicationListner으로 포트 정보 알아내기

package me.dsunni;

import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext;
import org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

@Component
public class PortListner implements ApplicationListener<ServletWebServerInitializedEvent> {

    @Override
    public void onApplicationEvent(ServletWebServerInitializedEvent servletWebServerInitializedEvent) {
        ServletWebServerApplicationContext applicationContext
                = servletWebServerInitializedEvent.getApplicationContext();
        System.out.println(applicationContext.getWebServer().getPort());
    }
}

웹서버가 초기화(생성)이 되면 EventListner가 호출된다.

  • getApplicationContext 서블릿 웹 서버의 컨텍스트이기 때문에 웹 서버를 알 수 있다. 그리고 그 웹서버를 통해 포트를 확인할 수 있다.

image

profile
https://dsunni.tistory.com/ 이사갑니답

2개의 댓글

comment-user-thumbnail
2021년 11월 4일

큰 도움이 되었습니다!!

답글 달기
comment-user-thumbnail
2023년 11월 29일

좋은 정보 감사합니다

답글 달기