Spring boot에서 Tomcat이 어떻게 실행될까?

Kevin·2024년 2월 29일
0

Spring

목록 보기
16/27
post-thumbnail

서론

외장 톰캣을 활용한 Spring MVC에서는 개발자가 작성한 코드가 WAR로 압축이 되고, 톰캣 WAS로 배포된 후, WAS 서버가 실행되어야 했다. 즉 서버의 실행 주체는 외장 톰캣이다.

내장 톰캣은 개발자 코드 이내의 하나의 라이브러리로 들어가서 동작을 하는 것이다.

Spring boot에 내장되어 작동하는 내장 Servlet 3.0+ 컨테이너는 ServletContainerInitializerWebApplicationInitializer 를 직접적으로 사용하지 않는다. 그 이유는 타사 코드의 설계가 응용 프로그램을 손상 시키지 못하게 하기 위해서이다.

그러면 어떤 방식으로 Spring boot는 Tomcat과 연결 될까?


HOW?

MySpringBootMain

import hello.boot.MySpringApplication;
import hello.boot.MySpringBootApplication;

@MySpringBootApplication // @ComponentScan 기능을 사용
public class MySpringBootMain {

    public static void main(String[] args) {
        System.out.println("MySpringBootMain.main");
        MySpringApplication.run(MySpringBootMain.class,args); //내장톰캣 설정및실행 클래스
    }
    
}

MySpringApplication

import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

import java.util.List;

public class MySpringApplication {

    public static void run(Class configClass, String[] args)  {

        System.out.println("MySpringApplication.main args =  " + List.of(args));
        
        //Tomcat 설정, 별도의 톰캣 설치없이 JAVA코드로 가능
        Tomcat tomcat = new Tomcat();
        Connector connector = new Connector();
        connector.setPort(8080);
        tomcat.setConnector(connector);

        // 스프링 컨테이너 생성
        AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
        appContext.register(configClass); //부트클래스 설정파일로 등록

        //스프링 MVC 디스패처 서블릿 생성, 스프링 컨테이너 연결
        DispatcherServlet dispatcher = new DispatcherServlet(appContext); // 스프링 컨테이너 추가

        //디스패처 서블릿 등록
        Context context = tomcat.addContext("","/");
        tomcat.addServlet("","dispatcher",dispatcher);
        context.addServletMappingDecoded("/","dispatcher"); // url이 /로 들어오면 dispacher 서블릿으로 빠지도록 설정.

		//톰캣 수행
        try {
            tomcat.start();
        } catch (LifecycleException e) {
            throw new RuntimeException(e);
        }
    }
}

main 메서드가 있는 MainApplication은 Main클래스이자, Component Scan 기능을 가진 Spring Bean 설정파일이다.

Spring 웹 환경은 SpringApplication이 생성하므로, run메소드에 Bean설정파일을 인수로 넘겨준다.

SpringApplication은 넘겨받은 Bean설정클래스로 IOC컨테이너(ApplicationContext)를 생성하고 생성된 IOC컨테이너를 초기화(refresh)하는 과정에서 웹서버(내장톰캣) 환경도 구성이 된다.

고로, SpringBoot는 단순 main메소드 실행 하나로, 웹서비스 환경 구성을 자동화한다.


위 과정의 흐름

컴포넌트 스캔 기능을 가진 MySpringBootMain(Spring 설정 클래스)를 생성한다.

그리고 MySpringBootMain는 MySpringApplication을 호출한다.

MySpringApplication은 스프링설정파일을 스프링컨테이너에 등록하고 스프링 컨테이너를 DispatcherServlet에 등록하고 DispatcherServlet을 내장톰캣에 등록한 뒤 내장톰캣을 실행하는 역할을 한다.


내가 이해한대로

Spring boot에서는 Tomcat이 Lombok과 같이 하나의 라이브러리로 들어가 있다.

Spring boot Application을 실행(=main 메서드를 실행)하면 스프링 설정 파일을 스프링 컨테이너에 등록하면서 DispactherServlet에 등록을 하고, 이 DispatcherServlet를 내장 톰캣에 등록하고, 내장 톰캣을 실행한다.

profile
Hello, World! \n

0개의 댓글