개요
그동안 많은 스프링 부트 프로젝트를 진행했지만 부끄럽게도 스프링과 스프링 부트의 차이점을 완벽히 이해하지 못한 채 개발을 진행했습니다.
저는 단순하게 "스프링 부트는 내장 톰캣 서버를 가지고 있는 스프링"이라고 생각했는데 토비님의 인프런 강의 초반부를 듣자마자 큰 착각이었다는 것을 깨달았습니다.
따라서 이번 게시글에서는 둘의 차이점을 명확하게 파악하기 위해 스프링 부트에 대해 정리해보겠습니다.
스프링 부트
Spring Boot는 스프링을 기반으로 실무 환경에 사용 가능한 수준의 독립실행형(stand-alone) 애플리케이션을 별다른 고민 없이 빠르게 개발할 수 있도록 도와주는 여러 가지 도구의 모음입니다.
스프링에서는 제공하는 선택지가 많고 스프링과 함께 사용하는 다양한 기술 및 라이브러리를 개발자가 직접 선택해야 하는 반면 스프링 부트의 경우 뒤에 언급할 opinionated 특성을 가지고 있어 업계에서 검증된 스프링 생태계 프로젝트, 표준 자바 기술, 오픈소스 기술의 종류와 의존관계 그리고 사용 버전까지 모두 정해줍니다.
보통 enterprise 애플리케이션은 web을 기반으로 하고 있으니까 개발한 코드를 war 파일과 같이 패키징을 한 뒤 서버에 배포를 하는 방식인데 비해 스프링 부트는 command line에서 java [클래스명] 혹은 jar로 압축해 놓은 코드라면 java -jar [jar명] 명령어를 실행하여 바로 전체 애플리케이션을 비교적 간단하게 실행할 수 있다는 것이 특징입니다.
스프링 부트의 핵심 목표
스프링 부트의 핵심 목표는 아래와 같습니다.
- 매우 빠르고 광범위한 영역의 스프링 개발 경험을 제공
- 즉시 적용 가능한 기술 조합을 제공하여 개발자가 큰 고민 없이 개발을 시작할 수 있도록 지원하되 유연성을 가져 필요에 따라 원하는 방식으로 손쉽게 변형 가능
- 내장형 서버, 보안, 메트릭, health check 그리고 외부 설정 방식과 같이 프로젝트에서 필요로 하는 다양한 비기능적인 기술을 제공
- 코드 생성이나 XML 설정을 필요로 하지 않음
- 스프링의 경우 XML 설정이 주된 방식이며 대표적인 예시로 web.xml이 존재
스프링 부트의 역사
스프링 부트는 스프링 프레임워크 프로젝트에 이슈로 등록된 "Containerless 웹 개발 아키텍처의 지원" 요청에서 논의가 시작되었고 마침내 2013년에 0.5.0.M1 버전과 함께 별도의 프로젝트로 공개되었습니다.
현재는 스프링 프레임워크의 6 버전과 호환되는 스프링 부트 3.0 버전까지 공개가 된 상태입니다.
https://github.com/spring-projects/spring-framework/issues/14521
Containerless란?
앞서 업급했드시 스프링 부트는 스프링 프레임워크의 "Containerless 웹 개발 아키텍처의 지원"을 위해 만들어진 프로젝트입니다.
따라서 Containerless의 정의에 대해 알아볼 필요가 있으며 이에 앞서 Web Component의 개념을 알아야 합니다.
Web Component
- Web Component는 서버에 동작하면서 기능을 제공해 주는 여러 가지 component를 제공하며 앞에 항상 web client가 필요
- Web Component의 핵심 기능은 동적 콘텐츠(dynamic content)이며 클라이언트가 요청을 주면 동적으로 콘텐츠를 생성한 뒤 응답
- Web Component는 Web Container 내에 있어야 하며 Web Container 내에는 여러 Web Component가 존재
- Web Container는 Web Component의 라이프사이클을 관리하며 클라이언트의 요청을 적절한 Web Component에 매핑 혹은 routing 하는 역할을 수행
- Spring에서는 Web Component가 Servlet, Web Container가 Servlet Container(Tomcat)
Containerless
- Containerless는 간단하게 요약하자면 Serverless와 유사한 개념
- Serverless란 서버에 대한 설치 및 관리와 같이 인프라 관련된 부분을 개발자들이 전혀 신경 쓰지 않고 서버 애플리케이션을 개발, 배포, 운영할 수 있다는 것이 특징
- 스프링에서는 Spring Container가 Servlet Container 뒤에 위치하며 클라이언트가 요청을 보내면 Servlet Conainer를 통해 Spring Container에 도달
- 이때 Spring Container는 받은 요청을 적절한 bean에 매핑한 뒤 Servlet Container에 응답하는 역할을 수행
- 스프링 부트는 Servlet Container 설정을 신경 쓰지 않고 개발 시작할 수 있도록 개발 도구와 아키텍처를 지원하며 이를 Containerless라고 함
정리하자면 스프링 부트는 스프링 애플리케이션 개발에 요구되는 Servlet Container의 설치, WAR 폴더 구조, web.xml, WAR 빌드, 컨테이너로 배치, 포트 바인딩, 클래스로더, 로깅 등과 같은 필요하지만 애플리케이션 개발의 핵심이 아닌 단순 반복 작업을 제거해 주는 개발 도구와 아키텍처를 지원합니다.
즉, 설치된 컨테이너로 배포하지 않고 standalone 자바 애플리케이션으로 동작합니다.
* 스프링 부트는 앞서 언급한 단순한 반복 작업을 아래와 같이 main() 함수 내에서 실행합니다.
스프링 부트의 특징: Opinionated
스프링 부트가 opinionated 특성을 갖게 된 배경을 이해하기 위해서는 스프링 프레임워크의 설계 철학에 대해 알 필요가 있습니다.
스프링 프레임워크의 설계 철학은 아래와 같습니다.
- 극단적인 유연함 추구
- 다양한 관점 수용
- not opnionated (개발자들로 하여금 모든 것을 선택하게끔 유도)
- 수많은 선택지를 다 포용
위와 같은 철학은 유연하다는 장점이 있지만 선택한 기술들의 버전 호환성 체크 및 의존 관계를 확인해야 한다는 문제점과 접근 방법부터 모색해야 한다는 점에서 상대적으로 시간이 오래 걸린다는 문제점이 존재합니다.
스프링 부트는 위 문제점을 해결하기 위해 opinionated 특성을 가져 업계에서 검증된 스프링 생태계 프로젝트, 표준 자바 기술, 오픈소스 기술의 종류와 의존관계 그리고 사용 버전까지 모두 정해줍니다.
스프링 부트에서 정해준 기술은 스프링에서 적용하는 방식(DI 구성)과 디폴트 설정값을 모두 제공하기 때문에 개발자들이 별 다른 고민 없이 개발을 진행할 수 있습니다.
또한, 원한다면 스프링 부트가 제시한 구성을 override 하거나 재구성하는 것이 가능한데 스프링 프레임워크의 설계 철학을 본받아 매우 안전하고 명료한 방법을 통해서 유연한 확장성을 제공합니다.
스프링 사용 방식을 완벽하게 이해한 경우 스프링 부트로 시작한 프로젝트의 애플리케이션 코드를 전혀 손대지 않고, 스프링 부트를 단계적으로 제거하는 것이 가능합니다.
이를 통해 스프링 부트처럼 기술과 구성을 간편하게 제공하는 본인만의 모듈 작성도 가능합니다.
스프링 부트를 이용한 개발자들의 한계 및 오해
스프링 부트를 이용한 개발자들이 공통적으로 지니는 한계 및 오해가 아래와 같이 존재합니다. (안타깝게도 저도 몇 가지 사항에 해당되며 강의를 들으며 고쳐나가고자 합니다.)
- 애플리케이션 기능 코드만 잘 작성하면 됨
- 스프링을 몰라도 구글링을 통해 개발 잘할 수 있음
- 부트가 직접적으로 보여주지 않는 부분은 모르고 넘어가도 됨
- 기술적인 문제가 발생하면 검색해서 해결 후 복기 X
하지만 스프링 부트가 현재의 모습을 띄게 되는 과정을 살펴보면서 스프링부트가 동작하는 기본 원리를 살펴보고, 이를 통해서 스프링이 제공하는 기능을 잘 활용하는 방법도 익혀나간다면, 이후 스프링 부트의 다양한 기능을 빠르게 파악하고 활용할 수 있는데 도움이 될 것입니다.
정리하자면 스프링 부트를 이해하게 될 경우 아래와 같이 적용이 가능합니다.
- 스프링 부트가 스프링의 기술을 어떻게 활용하는지 배우고 활용 가능
- 스프링 부트가 선택한 기술, 자동으로 만들어주는 구성 디폴트 설정이 어떤 것인지 확인 가능
- 필요시 부트의 기본 구성 수정 및 확장 가능
- 나만의 스프링 부트 모듈 만들어 활용 가능
출처
인프런 토비의 스프링 부트 - 이해와 원리
'Spring' 카테고리의 다른 글
[Spring Boot] 메타 애노테이션과 합성 애노테이션 (0) | 2023.03.06 |
---|---|
Spring 지원 없이 Servlet을 통해 Front Controller 구현 (0) | 2023.03.02 |
[SpringBoot] 구글 SMTP 통해 메일 보내기 (2) | 2022.04.10 |
[SpringBoot] BcryptPasswordEncoder (0) | 2022.04.03 |
[SpringBoot] 로그인된 사용자가 접근할 수 있는 기능 Test 작성하는 방법 (0) | 2022.04.02 |