Spring Boot 애플리케이션은
main메서드를 실행하기만 하면, 별도의 서버 설치 없이도 웹 서비스가 즉시 동작한다.
이 편리함 속에는 웹을 구동하는 핵심 구성 요소와 Spring의 객체 관리 메커니즘이 숨어있다. 이 '마법'처럼 보이는 현상을 이해하기 위해서는, 먼저 웹 서버와 WAS의 차이를 알아야 하고, Spring이 내부에서 객체(Bean)를 어떻게 찾아내고 관리하는지 파악해야 한다.
웹 서비스를 구성할 때, 이 두 용어는 자주 혼용되지만 명확한 역할 차이가 있다.
웹 서버는 HTTP 요청을 받아 정적(Static) 콘텐츠를 제공하는 서버다. 정적 콘텐츠란, 요청에 따라 변하지 않는 파일(HTML, CSS, JavaScript, 이미지)을 의미한다.
만약 웹 서버가 처리할 수 없는 동적인 요청이 들어오면, 웹 서버는 해당 요청을 WAS로 전달하는 중개자 역할도 수행한다.
WAS는 웹 서버의 기능에 더해, 애플리케A션 로직을 실행하여 동적(Dynamic) 콘텐츠를 생성하고 제공하는 서버다.
즉, WAS는 정적 콘텐츠 처리(웹 서버)와 동적 콘텐츠 처리(웹 컨테이너)를 모두 수행할 수 있는, 더 포괄적인 개념의 서버다.
그렇다면 Spring Boot를 실행할 때 별도로 설치하지 않았는데도 동작하는 '톰캣(Tomcat)'은 무엇일까?
main 메서드 실행 시, 그 자체로 하나의 완전한 WAS가 되어 서비스 요청을 처리할 수 있다.Spring의 핵심은 '제어의 역전(IoC)'이며, Spring IoC 컨테이너가 애플리케이션의 객체(Bean)를 생성하고 관리한다. 컨테이너가 객체를 관리하기 위해서는, 먼저 "어떤 객체들을 관리해야 하는지" 알려주는 'Bean 등록' 과정이 필요하다.
Spring Boot에서는 주로 다음 두 가지 방법을 사용한다.
가장 보편적이고 자동화된 방법이다.
@Component 어노테이션을 붙인다.@Component를 확장한 @Service (비즈니스 로직), @Repository (데이터 접근), @Controller, @RestController (웹) 등의 어노테이션도 모두 인식한다.@SpringBootApplication 어노테이션이 붙은 메인 클래스의 패키지를 기준으로 하위 패키지를 모두 스캔(Scan)한다. 이 과정에서 해당 어노테이션이 붙은 클래스들을 찾아 자동으로 IoC 컨테이너에 Bean으로 등록한다.컴포넌트 스캔으로 처리하기 어려운 Bean들을 수동으로 등록하는, 명시적이고 유연한 방법이다.
config 패키지 등에 @Configuration 어노테이션이 붙은 설정 클래스를 만든다. 그 후, Bean으로 등록하고자 하는 객체를 반환하는 메서드를 만들고 @Bean 어노테이션을 붙인다.@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;
}
}
Spring Boot 애플리케이션의 실행은 내장된 WAS(톰캣)를 구동시켜 그 자체로 웹 서버이자 애플리케이션 서버로 동작함을 의미한다. 이렇게 구동된 서버 내부에서 Spring 컨테이너는 @Component 스캔과 @Configuration 설정 등을 바탕으로 필요한 Bean(객체)들을 미리 준비하고, 개발자가 정의한 비즈니스 로직을 수행할 준비를 마친다.
이 두 가지 핵심 원리를 이해하는 것은 Spring Boot의 자동화된 편리함 이면의 동작 방식을 파악하고, 문제 발생 시 더 깊이 있는 트러블슈팅을 가능하게 하는 기반이 된다.