ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring Boot 핵심 기능 1 - 내장 톰캣
    BackEnd/Spring Boot 2023. 3. 25. 11:30
    반응형

      이전에는 웹 애플리케이션을 구동하고 싶으면 웹 애플리케이션 서버(WAS)를 별도로 설치하고, 웹 애플리케이션 빌드 파일(WAR)을 배포해야 했습니다.

     

    WAR 배포 방식의 단점

    • 톰캣 같은 WAS를 별도로 설치해야 합니다.
    • 개발 환경 설정이 복잡합니다.
    • 배포 과정이 복잡합니다.
    • 톰캣의 버전을 변경하려면 톰캣을 다시 설치해야 합니다.

     

      이런 문제를 해결하기 위해 톰캣을 라이브러리로 제공하는 내장 톰캣(embed tomcat) 기능을 제공합니다.

     

    외장 서버 vs 내장 서버

    • 외장 서버: 웹 애플리케이션 서버에 WAR 파일을 배포하는 방식으로 WAS를 실행해서 동작합니다.
    • 내장 서버: 애플리케이션 JAR 안에 다양한 라이브러리들과 WAS 라이브러리가 포함되는 방식으로 main() 메서드를 실행해서 동작합니다.

     

    스프링 부트와 웹 서버

      스프링 부트는 내장 톰캣을 사용해서 빌드와 배포를 편리하게 해주며, 빌드 시 하나의 Jar를 사용합니다. spring-boot-starter-web를 사용하면 내부에서 내장 톰캣을 사용합니다. 라이브러리 의존 관계를 따라가보면 내장 톰캣(tomcat-embed-core)이 포함된 것을 확인할 수 있습니다.

     

    스프링 부트와 웹 서버 실행 과정

    package hello.boot;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class BootApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(BootApplication.class, args);
    	}
    
    }
    • 스프링 부트를 실행할 때는 자바 main() 메서드에서 SpringApplication.run()을 호출해주면 됩니다.
    • 여기에 메인 설정 정보를 넘겨주는데, 보통 @SpringBootApplication 애노테이션이 있는 현재 클래스를 지정해주면 됩니다.
    • @SpringBootApplication 애노테이션 안에는 컴포넌트 스캔을 포함한 여러 기능이 설정되어 있는데, 기본 설정은 현재 패키지와 그 하위 패키지 모두를 컴포넌트 스캔합니다.

     

      단순해 보이는 코드 한줄 안에는 수 많은 일들이 발생하지만 핵심은 2가지 입니다.

    1. 스프링 컨테이너 생성
      org.springframework.boot.web.servlet.context.ServletWebServerApplicationContextFactory

       

    2. WAS(내장 톰캣) 생성
      org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory

    스프링 부트와 웹서버 빌드와 배포

      내장 톰캣이 포함된 스프링 부트를 빌드하면 build/libs/boot-0.0.1-SNAPSHOT.jar 파일이 만들어집니다.

    [jar 빌드]: ./gradlew clean build
    [Window OS]: gradlew clean build

      jar 파일이 있는 폴더로 이동 후 다음 명령어로 jar 파일을 실행하면 스프링 부트 애플리케이션이 실행됩니다.

    java -jar boot-0.0.1-SNAPSHOT.jar

    Note. 빌드 결과를 보면 boot-0.0.1-SNAPSHOT-plain.jar 파일도 보이는데, 이것은 우리가 개발한 코드만 순수한 jar로 빌드한 것입니다.

     

    스프링 부트 jar 분석

      build/libs 폴더로 이동하여 다음 명령어를 사용해서 압축을 풉니다. 

    jar -xvf boot-0.0.1-SNAPSHOT.jar

    Note. WAR와 다르게 JAR 파일은 내부에 라이브러리 역할을 하는 JAR 파일을 포함할 수 없습니다. 포함한다고 해도 인식이 되지 않습니다(JAR 파일 스펙의 한계). 대안으로 Fat Jar가 있으나 어떤 라이브러리가 포함되어 있는지 확인하기 어려우며, 파일명 중복을 해결할 수 없습니다. 스프링 부트는 이런 문제를 해결하기 위해 jar 내부에 jar를 포함할 수 있는 특별한 구조의 jar를 만들고 동시에 만든 jar를 내부 jar를 포함해서 실행할 수 있게 합니다. 이것을 실행 가능 Jar(Executable Jar)라고 합니다.

    실행 가능 Jar 내부 구조

     

    Jar 실행 정보

    [META-INF/MANIFEST.MF]

      Manifest-Version: 1.0
      Main-Class: org.springframework.boot.loader.JarLauncher
      Start-Class: hello.boot.BootApplication
      Spring-Boot-Version: 3.0.2
      Spring-Boot-Classes: BOOT-INF/classes/
      Spring-Boot-Lib: BOOT-INF/lib/
      Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
      Spring-Boot-Layers-Index: BOOT-INF/layers.idx
      Build-Jdk-Spec: 17
    1. java -jar xxx.jar를 실행하게 되면 우선 META-INF/MANIFEST.MF 파일을 찾습니다.
    2. Main-Class가 JarLauncher를 실행합니다. JarLauncher는 스프링 부트가 빌드 시에 넣어주며, org/springframework/boot/loader/JarLauncher에 포함되어 있습니다(스프링 부트는 jar 내부에 jar를 읽어들이는 기능이 필요하며, 특별한 구조에 맞게 클래스 정보도 읽어들여야 하는데 이런 일을 JarLauncher가 처리합니다).
    3. Start-Class에 지정된 main() 메서드를 호출합니다.

     

    Note. Main-Class를 제외한 나머지는 자바 표준이 아닙니다. 스프링 부트가 임의로 사용하는 정보입니다.

     

    Note. 실행 가능 Jar가 아니라, IDE에서 직접 실행할 때는 BootApplication.main()을 바로 실행합니다. IDE가 필요한 라이브러리를 모두 인식할 수 있게 도와주기 때문에 JarLauncher가 필요하지 않습니다.

     

    [참고정보]

    스프링 부트 - 핵심 원리와 활용

    반응형

    'BackEnd > Spring Boot' 카테고리의 다른 글

    Spring Boot 핵심 기능 3 - 자동 구성(Auto Configuration)  (0) 2023.04.20
    Spring Boot 핵심 기능 2 - 라이브러리 관리  (0) 2023.04.19
    REST API  (0) 2022.05.25
    HAL Browser  (0) 2022.05.25
    Actuator  (0) 2022.05.20

    댓글

Designed by Tistory.