Spring Boot는 어떻게 스스로 동작하는가 (WAS, Bean 등록)

nbh·2025년 11월 3일

Spring Boot는 어떻게 스스로 동작하는가 (WAS, Bean 등록)

Spring Boot 애플리케이션은 main 메서드를 실행하기만 하면, 별도의 서버 설치 없이도 웹 서비스가 즉시 동작한다.

이 편리함 속에는 웹을 구동하는 핵심 구성 요소와 Spring의 객체 관리 메커니즘이 숨어있다. 이 '마법'처럼 보이는 현상을 이해하기 위해서는, 먼저 웹 서버와 WAS의 차이를 알아야 하고, Spring이 내부에서 객체(Bean)를 어떻게 찾아내고 관리하는지 파악해야 한다.


1. 웹 서버(Web Server) vs WAS(Web Application Server)

웹 서비스를 구성할 때, 이 두 용어는 자주 혼용되지만 명확한 역할 차이가 있다.

A. 웹 서버 (Web Server): 정적 콘텐츠 담당

웹 서버는 HTTP 요청을 받아 정적(Static) 콘텐츠를 제공하는 서버다. 정적 콘텐츠란, 요청에 따라 변하지 않는 파일(HTML, CSS, JavaScript, 이미지)을 의미한다.

  • 주요 기능: HTTP 프로토콜을 통해 클라이언트의 요청을 받고, 이미 준비된 정적 파일을 응답으로 전송한다.
  • 대표 예시: Nginx, Apache HTTP Server

만약 웹 서버가 처리할 수 없는 동적인 요청이 들어오면, 웹 서버는 해당 요청을 WAS로 전달하는 중개자 역할도 수행한다.

B. WAS (Web Application Server): 동적 콘텐츠 담당

WAS는 웹 서버의 기능에 더해, 애플리케A션 로직을 실행하여 동적(Dynamic) 콘텐츠를 생성하고 제공하는 서버다.

  • 주요 기능: 클라이언트의 요청에 따라 Java 코드(비즈니스 로직)를 실행하고, 데이터베이스를 조회하며, 그 결과를 바탕으로 새로운 HTML 페이지나 JSON 데이터를 생성하여 응답한다.
  • 핵심 구성: 웹 서버 기능 + 웹 컨테이너(Web Container).
    • Java 진영에서는 '서블릿 컨테이너'(Servlet Container)가 이 역할을 하며, 서블릿(Servlet)의 생명주기를 관리하고 동적 요청을 처리한다.
  • 대표 예시: Apache Tomcat, JBoss, WebLogic

즉, WAS는 정적 콘텐츠 처리(웹 서버)와 동적 콘텐츠 처리(웹 컨테이너)를 모두 수행할 수 있는, 더 포괄적인 개념의 서버다.

Spring Boot의 내장 톰캣(Embedded Tomcat)

그렇다면 Spring Boot를 실행할 때 별도로 설치하지 않았는데도 동작하는 '톰캣(Tomcat)'은 무엇일까?

  • 톰캣은 전통적인 WAS(정확히는 서블릿 컨테이너)다.
  • Spring Boot는 이 톰캣을 내장(Embedded)하고 있다. 즉, Spring Boot 애플리케이션을 실행하면, 애플리케이션 코드 내에서 톰캣 서버가 함께 구동된다.
  • 따라서 Spring Boot는 main 메서드 실행 시, 그 자체로 하나의 완전한 WAS가 되어 서비스 요청을 처리할 수 있다.

2. Spring은 객체(Bean)를 어떻게 관리하는가?

Spring의 핵심은 '제어의 역전(IoC)'이며, Spring IoC 컨테이너가 애플리케이션의 객체(Bean)를 생성하고 관리한다. 컨테이너가 객체를 관리하기 위해서는, 먼저 "어떤 객체들을 관리해야 하는지" 알려주는 'Bean 등록' 과정이 필요하다.

Spring Boot에서는 주로 다음 두 가지 방법을 사용한다.

A. 컴포넌트 스캔 (Component Scanning)

가장 보편적이고 자동화된 방법이다.

  • 사용 방법: 클래스에 @Component 어노테이션을 붙인다.
    • Spring은 @Component를 확장한 @Service (비즈니스 로직), @Repository (데이터 접근), @Controller, @RestController (웹) 등의 어노테이션도 모두 인식한다.
  • 동작 방식: Spring Boot가 실행될 때, @SpringBootApplication 어노테이션이 붙은 메인 클래스의 패키지를 기준으로 하위 패키지를 모두 스캔(Scan)한다. 이 과정에서 해당 어노테이션이 붙은 클래스들을 찾아 자동으로 IoC 컨테이너에 Bean으로 등록한다.
  • 장점:
    • 매우 간편하다. 어노테이션 하나만 붙이면 자동으로 등록된다.
    • "관심사에 따라 어노테이션을 분리"하여 코드의 역할을 명확하게 드러낼 수 있다.
  • 단점:
    • 내가 직접 코드를 수정할 수 없는 외부 라이브러리의 클래스는 이 방법으로 등록할 수 없다.
    • 등록하려는 Bean의 초기화에 복잡한 로직이 필요할 경우 구현이 제한된다.

B. Java 설정 파일 (Java Configuration)

컴포넌트 스캔으로 처리하기 어려운 Bean들을 수동으로 등록하는, 명시적이고 유연한 방법이다.

  • 사용 방법: config 패키지 등에 @Configuration 어노테이션이 붙은 설정 클래스를 만든다. 그 후, Bean으로 등록하고자 하는 객체를 반환하는 메서드를 만들고 @Bean 어노테이션을 붙인다.
  • 동작 방식: Spring 컨테이너는 @Configuration 클래스를 먼저 인식하고, 해당 클래스 내부의 @Bean 어노테이션이 붙은 메서드들을 실행한다. 그리고 그 메서드가 반환하는 객체를 IoC 컨테이너에 Bean으로 등록한다.
// 예: 외부 라이브러리의 ObjectMapper를 Bean으로 등록하는 경우
@Configuration
public class AppConfig {

    @Bean
    public ObjectMapper objectMapper() {
        // 이 메서드 안에서 복잡한 초기화 로직 수행 가능
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        return mapper;
    }
}
  • 장점:
    • 외부 라이브러리의 클래스도 Bean으로 등록할 수 있다.
    • 메서드 내에서 객체 생성 및 초기화 로직을 자유롭게 구현할 수 있어 유연성이 높다.
    • Bean 등록 과정을 개발자가 명시적으로 제어할 수 있다.
  • 단점:
    • 등록할 Bean이 많아지면 설정 코드가 길어지고 번거롭다.
    • 모든 클래스를 이 방식으로 등록하면 컴포넌트 스캔의 편리함을 잃게 된다.

결론

Spring Boot 애플리케이션의 실행은 내장된 WAS(톰캣)를 구동시켜 그 자체로 웹 서버이자 애플리케이션 서버로 동작함을 의미한다. 이렇게 구동된 서버 내부에서 Spring 컨테이너는 @Component 스캔과 @Configuration 설정 등을 바탕으로 필요한 Bean(객체)들을 미리 준비하고, 개발자가 정의한 비즈니스 로직을 수행할 준비를 마친다.

이 두 가지 핵심 원리를 이해하는 것은 Spring Boot의 자동화된 편리함 이면의 동작 방식을 파악하고, 문제 발생 시 더 깊이 있는 트러블슈팅을 가능하게 하는 기반이 된다.

0개의 댓글