본문 바로가기

Spring Boot

Spring Boot와 내장 톰캣

728x90

내장 톰캣은 WAR 방식의 단점을 보완하기 위해서 등장하였습니다. (참고: 외장 서버와 내장 서버)

 

내장 톰캣은 쉽게 말해 톰캣을 라이브러리로 포함하고 자바 코드로 직접 실행하는 것을 의미합니다. 이번 포스팅에서는 내장 톰캣을 이용하여 Spring과 연결하여 웹 애플리케이션을 만들어보는 과정을 작성하였습니다. 사용할 코드의 패키지 구조와 build.gradle 구조는 아래와 같습니다.


 


plugins {
    id 'java'
}

group = 'hello'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

repositories {
    mavenCentral()
}

dependencies {
    //스프링 MVC 추가
    implementation 'org.springframework:spring-webmvc:6.0.4'

    //내장 톰켓 추가
    implementation 'org.apache.tomcat.embed:tomcat-embed-core:10.1.5'
}

 

내장 톰캣 생성

우선, 내장 톰캣을 생성하는 코드를 작성해 보겠습니다. EmbedTomcatSpringMain 클래스에 아래와 같은 코드를 작성합니다.


package hello.embed;

import hello.servlet.MyServlet;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;

import java.io.IOException;
import java.nio.file.Files;

public class EmbedTomcatSpringMain {
    public static void main(String[] args) throws LifecycleException, IOException {
        System.out.println("EmbedTomcatServletMain.main");

        // tomcat 설정
        Tomcat tomcat = new Tomcat();
        Connector connector = new Connector();
        connector.setPort(8080); // port 지정
        tomcat.setConnector(connector); // tomcat을 port 8080에 연결

	  // Window 환경에서는 아래와 같이 임시폴더를 생성하고 docBase를 넘겨주어야 합니다.
        String docBase = Files.createTempDirectory("tomcat-basedir").toString(); 
        
        // Servlet 등록
        Context context = tomcat.addContext("", docBase); // tomcat에 사용할 contextPath, docBase 지정
        tomcat.addServlet("", "myServlet", new MyServlet()); // tomcat에 Servlet 등록
        context.addServletMappingDecoded("/my-servlet", "myServlet"); // 등록한 Servlet의 경로 mapping
        tomcat.start(); // tomcat 시작

    }
}
  • docBase: 해당 웹어플리케이션에 대한 Document Base (Context Root로도 알려져 있습니다) 디렉터리, 또는 웹애플리케이션 아카이브 파일의 경로명(웹애플리케이션을 WAR 파일로 직접 실행하는 경우)을 나타냅니다. 이 디렉터리나 WAR 파일에 대한 절대경로명을 지정할 수도 있고, 이 Context가 정의된 Host의 appBase 디렉터리에 대한 상대경로명을 지정할 수도 있습니다.
    • 아래 포스팅을 참고하면 더 자세한 내용을 확인할 수 있습니다.

https://findmypiece.tistory.com/115

 

Tomcat appBase, docBase

로컬에서 Tomcat 을 구동하고 http://localhost:8080/ 로 접근했을 때 화면에 보여줄 자원(html 등) 을 찾는 기본적으로 경로는 Tomcat 설치 디렉토리 아래 있는 webapps/ROOT 디렉토리이고 이를 Document Root라고

findmypiece.tistory.com

https://velog.io/@kiwonkim/Web-%EC%9B%B9-%EC%96%B4%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98%EC%9D%B4%EB%9E%80

 

[Web] 웹 어플리케이션이란?

웹 서버 + WAS 를 통해 정적, 동적 컨텐츠를 모두 제공하는 웹 프로그램. 루트폴더인 webapps 내에 여러 웹 어플리케이션이 저장된다. 'app1' 이 웹 어플리케이션의 이름이자 루트폴더가 된다. 정적 컨

velog.io


위에서 등록한 MyServlet.class는 아래와 같이 생성하였습니다.


package hello.servlet;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;

public class MyServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("MyServlet.service");
        resp.getWriter().println("hello my servlet!");
    }
}

위 코드를 실행한 뒤, postman 혹은 웹 브라우저에 http://localhost:8080/my-servlet을 입력하면 응답이 아래와 같이 잘 나오는 것을 확인할 수 있습니다. 그리고 console 창에서 MyServlet.service도 출력됨을 확인할 수 있습니다.


Postman
console

 

이렇게 내장 톰캣을 통해 IDE에 별도 복잡한 톰캣 설정 및 톰캣 설치 과정 필요없이 main() 메서드만 실행해도 편리하게 웹 애플리케이션을 실행할 수 있습니다. 

사실 내장 톰캣을 개발자가 다룰 일은 거의 없고, 스프링 부트에서 내장 톰캣과 관련된 부분을 거의 대부분 자동화해줍니다. 따라서 내장 톰캣을 깊이 있게 학습하는 것은 권장하지 않습니다. (이미 다른 것도 공부할게 많으니까요 ㅎㅎㅎ)


내장 톰캣과 스프링 연결

이번에는 위에서 생성한 톰캣과 스프링을 연결해 보겠습니다.


public class EmbedTomcatSpringMain {
    public static void main(String[] args) throws LifecycleException, IOException {
        System.out.println("EmbedTomcatServletMain.main");

        // tomcat 설정
        Tomcat tomcat = new Tomcat();
        Connector connector = new Connector();
        connector.setPort(8080); // port 지정
        tomcat.setConnector(connector); // tomcat을 port 8080에 연결

        // 스프링 컨테이너 생성
        AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
        applicationContext.register(MyConfig.class); // config 파일 등록

        // 스프링 MVC Dispatcher Servlet 생성 + 스프링 컨테이너 연결
        DispatcherServlet dispatcherServlet = new DispatcherServlet(applicationContext);


        String docBase = Files.createTempDirectory("tomcat-basedir").toString();
        // Dispatcher Servlet 등록
        Context context = tomcat.addContext("", docBase); // tomcat에 사용할 contextPath, docBase 지정

        // tomcat.addServlet("", "myServlet", new MyServlet()); // tomcat에 Servlet 등록
        // context.addServletMappingDecoded("/my-servlet", "myServlet"); // 등록한 Servlet의 경로 mapping

        tomcat.addServlet("", "dispatcher", dispatcherServlet); // tomcat에 Dispatcher Servlet 등록
        context.addServletMappingDecoded("/", "dispatcher"); // 등록한 Dispatcher Servlet의 경로 mapping


        tomcat.start(); // tomcat 시작

    }
}

MyConfig.classMyController.class는 아래와 같이 작성하였습니다.


@Configuration
public class MyConfig {

    @Bean
    public MyController helloController() {
        return new MyController();
    }
}

@RestController
public class MyController {

    @GetMapping("/hello-spring")
    public String hello() {
        System.out.println("MyController.hello");
        return "hello spring!";
    }

}

 


[실행 결과]


Postman

 

console

 

 

위 과정을 정리하면 아래와 같습니다.

  1. 내장 톰캣을 생성하여 8080 port로 연결하도록 설정합니다.
  2. Spring Container를 만들고, 필요한 bean을 등록합니다. (MyConfig.class)
  3. 스프링 MVC Dispatcher Servlet을 만들고, 앞서 만든 Spring Container에 연결합니다.
  4. Dispatcher Servlet을 내장 톰캣에 등록합니다.
  5. 내장 톰캣을 실행하면, 연결된 Servlet이 실행되면서 Spring Container도 실행되게 됩니다.

 

이렇게, 내장 톰캣을 이용하여 Spring과 연결함으로써 편리하게 main() 메서드만 실행해서 실행할 수 있었습니다.

 

다음 포스팅에서는 위에서 진행한 내장 톰캣 실행, Spring Container 생성, Dispatcher Servlet 등록의 모든 과정을 편리하게 처리해 주는 나만의 Boot 클래스를 만들어봄으로써, Spring Boot가 어떻게 동작하는지 확인해 보도록 하겠습니다!

 


[참고 자료]

김영한, " 스프링 부트 - 핵심 원리와 활용", 인프런

 

728x90
반응형