백엔드/스프링&스프링부트

[인프런-토비] 01 Spring Boot 살펴보기

묘걍 2023. 12. 28. 21:50

👉🏻 스프링부트란 무엇인가?

스프링부트 개발자들이 명확하게 정의하지는 않았음

스프링부트는 스프링을 기반으로 실무 환경에 사용 가능한 수준의 독립 실행형 애플리케이션을 복잡한 고민 없이 빠르게 작성할 수 있게 도와주는 여러가지 도구의 모음이다

🧩 도구의 모음

  • 툴, 도구, (추상화된 틀을 제공하고 거기에 맞춰 애플리케이션을 개발할 수 있게 해주는)프레임워크, (여러 유용한 클래스 라이브러리를 제공해주는)라이브러리 이 모든 것이 다 들어 있다
    • 스프링 개발을 도와주는 다양한 도구의 모음
    • 스프링 자체를 확장하는 프레임워크
    • 더 유용한 라이브러리

🧩 스프링을 기반

  • 스프링부트는 스프링을 기반으로 한 애플리케이션을 잘 만들 수 있게 도와주는 도구이자 기술
    • 스프링 부트로 스프링 애플리케이션을 만든다!

🧩 독립 실행형 애플리케이션

  • Stand Alone Application이라고도 함
  • Enterprise Application
    • 웹을 기반으로함
    • 개발 후 개발코드를 Web Application Archive라고 하는 .war파일 형태로 패키징 후 서버에 배포, 그 위에서 동작 시킴
  • Spring Boot는 command line에서 Java를 실행하여 특정 클래스를 지정하여 애플리케이션을 실행하거나, 또는 미리 패키지화된 JAR 파일을 사용하여 전체 애플리케이션을 실행할 수 있도록 만들어졌다
  • command line에서는 'java' 명령어 뒤에 실행하려는 클래스의 이름을 지정하거나, 패키지화된 JAR 파일을 'java -jar' 명령어로 실행할 수 있다

🧩 복잡한 고민이 필요 없다

  • 기존 스프링으로 개발하는 것은 복잡한 고민이 필요했다
  • 생각보다 시작을 빠르게 하기가 어려웠다
    • 스프링을 어떻게 사용할지에 대한 많은 고민이 필요했음
    • 제공하는 많은 선택지 중에서, 다양한 표준 기술과 라이브러리 중에서 어떤 것을 어떻게 사용할 것인가에 대한 고민
  • 스프링부트는 그런 고민 없이 일단 빠르게 작성할 수 있게 해준다
  • 스프링 부트가 등장하던 당시에 커멘드라인에서 몇 줄만 치면 당장 코딩이 가능한 프로젝트가 생성되고, 몇가지 작업만 하면 DB도 연결되고, 웹페이지도 리턴해주는.. 애플리케이션을 빠르게 작성할 수 있는 고속개발이 가능한 툴이 인기가 있었다
  • 스프링으로 애플리케이션을 개발하지만 빠르게 개발할 수 있게 해주는 장점!!
  • 고민하지 않는다 = 결정을 해준다
    • 프로토타입을 만들고, MVP - 기본적 기능을 가진, 앱을 빠르게 출시하는 것에는 유리
    • 문제: 본격적인 엔터프라이즈 애플리케이션, 혹은 대규모 서비스 가능한 수준의 애플리케이션으로 확장하다보면 한계에 부딪히고 필요한 도구들이 부족한 경험을 하게 된다
    • 기업이나 현업에서 중요한 시스템을 만들 때 운영환경에서 꼭 필요한 것들, 실무 환경에 필요한 것들을 집어 넣어놨다
    • 빠르게 만들지만 이것들을 통해 계속 성장하는 서비스, 대규모 서비스에도 적용할 수 있게 여러 부분을 도와준다

🧩 스프링 ≠ 스프링 부트

  • 서로 다른 것!
  • 버전도 다르다
    • 부트가 스프링 버전을 결정해주기 때문에 스프링부트버전만 알면 스프링 버전을 알 수 있긴 하다

👉🏻 스프링 부트의 핵심 목표

▶️ 매우 빠르고 광범위한 영역의 스프링 개발 경험을 제공

  • 요즘 나온 주요한 기술들을 포괄적으로 (기존 스프링이 제공했던 기술을 넘어서는 수준으로) 제공

▶️  강한 주장을 가지고 즉시 적용 가능한 기술 조합을 제공하면서, 필요에 따라 원하는 방식으로 손쉽게 변형 가능

  • 빠름
  • 고민 없이 개발하도록
  • ~~를 사용해서 ~~방식으로 구성해서 개발하라고 결정해버림
  • 원할 때 언제든 변경 가능

▶️  프로젝트에서 필요로하는 다양한 비기능적인 기술(내장형 서버, 보안, 메트릭, 상태 체크, 외부 설정 방식 등) 제공

  • Stand alone을 위한 내장형 서버...

▶️  코드 생성이나 XML 설정을 필요로 하지 않음

  • 스프링은 원래 XML을 이용하는 게 주된 설정 방법이었음
  • 스프링부트는 XML이 없는 스프링 개발을 목표로
  • 많은 기술들이 코드 생성 방식으로 기능을 제공하는 경우가 많은데, 스프링부트는 코드를 생성해서 코드를 만져야하는방식으로 기술을 제공하지 않는다
  • 더 영리하고 효과적인 방식 제공

 


👉🏻 스프링 부트의 역사

2012년 스프링 프레임워크 프로젝트 이슈로 등록된 "Containerless 웹 개발 아키텍처의 지원" 요청에서 논의와 개발 시작

https://github.com/spring-projects/spring-framework/issues/14521

 

Improved support for 'containerless' web application architectures [SPR-9888] · Issue #14521 · spring-projects/spring-framewor

Mike Youngstrom opened SPR-9888 and commented As the enterprise development landscape grows more diverse the simpler the application framework the more likely developers are to adopt the framework....

github.com

  • 스프링 프레임워크 기능을 개선해달라고 스프링 프로젝트 이슈 트래커에 한 개발자가 올린 글로부터 출발
  • "Containerless 웹 개발 아키텍처를 위해서 스프링 기능 개선 요청"
    • Enterprise 개발 지형이 계속 확장, 다양화, 단순화된 방식의 접근 방법 선호
    • 전통적으로 스프링 웹 애플리케이션은 컨테이너 안에 배포 및 동작하는 방식으로 개발
      • 이를 위해 알아야 할 기본 지식이 너무 많다
    • 스프링은 Fojo라 불리는 단순한 Java Object, 거기에 결합된 다양한 서비스들을 이용해 손쉽게 개발이 가능하도록 개발 프로그래밍 모델을 가지고 있다
    • 이걸 전통적인 Java 웹 개발환경에 적용하기 위해 알아야할 지식이 많음 (=진입장벽)
    • Ruby on Rails, Node.js, Python등의 인기 있는 프레임워크처럼 단순한 방식으로, 기본 지식 없이도 개발을 빠르게 할 수 있고 사용이 편리한 것들에 비해서 뒤쳐져있다고 이야기
  • 스프링 개발자들은 이러한 요구사항을 수용하되, 새로운 프로젝트를 시작하는 게 낫겠다고 판단
  • 2013년 Phil Webb(Spring Boot 프로젝트 리더)의 댓글

  • Spring을 고치기보다는 Spring Boot라고 이름 붙인 새로운 프로젝트를 시작하기로 결정했다

🧩2013년 0.5.0.M1 공개

https://github.com/spring-projects/spring-boot

 

GitHub - spring-projects/spring-boot: Spring Boot

Spring Boot. Contribute to spring-projects/spring-boot development by creating an account on GitHub.

github.com

https://spring.io/blog/2013/08/06/spring-boot-simplifying-spring-for-everyone/

 

Spring Boot – Simplifying Spring for Everyone

(This blog post was written jointly by Phil Webb and Dave Syer). We are pleased to announce the first milestone release of a new project called Spring Boot. Spring Boot aims to make it easy to create Spring-powered, production-grade applications and servic

spring.io

  • 스프링 개발자들 열광
    • 편리, 빠름
    • 그러면서도 스프링의 가치를 그대로 지킴

🧩 2014년 1.0 GA 공개

https://spring.io/blog/2014/04/01/spring-boot-1-0-ga-released/

 

Spring Boot 1.0 GA Released

On behalf of the entire Spring Boot team, I am very pleased to announce the general availability of Spring Boot 1.0! You can download the 1.0.1 with an important security fix here. You'll find everything you need to get going at projects.spring.io/spring-b

spring.io

  • 1.0 정식 버전 공개

🧩 2018년

  • 2.0 공개
  • 스프링5를 지원하기 시작

https://spring.io/blog/2018/03/01/spring-boot-2-0-goes-ga/

 

Spring Boot 2.0 goes GA

On behalf of the team, it is my very great pleasure to announce that Spring Boot 2.0 is now generally available as 2.0.0.RELEASE from repo.spring.io and Maven Central! This release is the culmination of 17 months work and over 6800 commits by 215 different

spring.io

🧩 2022년 10월

  • 스프링부트 2.7.5버전 공개

https://spring.io/blog/2022/10/20/spring-boot-2-7-5-available-now/

 

Spring Boot 2.7.5 available now

 

spring.io

 

 

Spring Boot가 컨테이너리스 웹 애플리케이션 아키텍처를 지원해달라는 요청으로 출발해서 지금까지 발전해온 것


👉🏻 Containerless (컨테이너리스 웹 애플리케이션 아키텍처)

  • SpringBoot는 스프링이 컨테이너리스 웹 애플리케이션 아키텍처를 지원해줬으면 좋겠다는 요청으로 출발
  • Serverless와 유사하다
    • 서버에 대한 설치, 관리 이런 부분들을 개발자들이 신경쓰지 않고 서버 애플리케이션을 개발해 배포하고 운영하는 게 가능하도록 만드는 방법
  • Containerless
    • 컨테이너가 필요 없다는 뜻이 아님
    • 컨테이너 관리를 신경쓰지 않아도 된다

👉🏻 Container

  • 스프링 = IOC 컨테이너
    • 스프링 컨테이너라고도 부른다
  • 그럼 스프링 프레임 워크를 스프링 컨테이너를 쓰지 말자는 이야기인가??

🧩 Web Component

웹 프로그램을 개발한다는 것은 서버에서 동작하면서 기능을 제공해주는 여러가지 컴포넌트를 만드는 것이다.

웹 컴포넌트를 만들었다고 했을 때, (회원가입 기능을 담당하는 웹 컴포넌트)

- 웹 컴포넌트는 서버에 존재

- 혼자서는 일을 하지 못한다

- 그 앞에 웹 클라이언트가 필요하다

- 웹 클라이언트가 요청을 주면 그때 웹 컴포넌트가 일을 한다

- 웹 컴포넌트의 주요한 목표는 다이나믹 콘텐츠를 만드는 것이다

- 우리가 다이나믹하게 매번 바뀌는 컨텐츠가 아니라 항상 고정되어 있는 똑같은 페이지를 띄운다면

   굳이 웹 컴포넌트를 만들지 않아도 된다

    그냥 웹 서버 위에 정적인 리소스를 올려놓고 항상 똑같은 화면을 보여주면 된다

- 웹 컴포넌트를 만들어 이 안에 코드를 작성한다는 것은 동적인 콘텐츠를 만들어

   이것을 다시 클라이언트에게 응답으로 보내주는 것

- 웹은 항상 요청과 응답 쌍으로 돌아간다

- 요청을 처리하는 하나 이상의 웹 컴포넌트가 존재한다

- 웹 컴포넌트는 웹 컨테이너 안에 들어가 있어야 한다

🧩 Web Container

✅ 라이프사이클 관리, 일생 주기 관리

  • 서버쪽에 떠 있는 웹 컴포넌트
  • 이 웹 컴포넌트를 서비스가 되는 동안 계속 메모리 위에서 동작하도록 관리해주는 작업 필요
    • 컴포넌트를 메모리에 올리고 new → 진입이 되는 클래스 인스턴스를 생성 ...

✅ 다양한 종류의 웹 컴포넌트 관리

  • 웹 컨테이너는 일반적으로 하나의 웹 컴포넌트만 가지고 있지 않다
  • 웹 컨테이너가 제공하는 서비스를 담당하는 많은 종류의 컴포넌트를 가지고 있을 수 있다
    • 회원가입, 로그인, 조회, 주문, ...

✅ 라우팅, 매핑

  • 클라이언트로부터 들어온 요청을 어느 컴포넌트가 담당할지 결정해서 연결해주는 작업
  • 정해진 룰에 따라 해당하는 컴포넌트에 요청을 넘겨준다
  • 스프링에서 핸들러 매핑이라고 하는 것..

✅ Survlet Container

  • 자바에서는 웹 컴포넌트를 Survlet이라고 한다
  • 이 Survelt들을 관리해주는 컨테이너를 Survelt 컨테이너라고 부른다
    • Tomcat 등..

- Survlet container 안에 Servlet들을 여러 개 띄워 놓고 그 다음 맵핑 정보를 넣으면

  요청에 따라 확정 서블릿이 그 요청을 처리할 수 있도록 하고

  응답을 생성해서 다시 클라이언트 브라우저나 API를 호출한 클라이언트한테 돌려주는 작업 담당

- 이것은 너무 제한적이고 좀 더 나은 방법으로 개발할 수 있으면 좋겠다 해서 만들어진 게 스프링 프레임워크

✅ Spring Container

- 그렇다고 스프링 컨테이너가 서블릿 컨테이너를 대체하는 것은 아니다

- 스프링 컨테이너는 서블릿 컨테이너 뒷쪽에 위치

- 스프링 컨테이너에 들어가는 컴포넌트는 Bean이라고 부른다

- 여러개의 빈을 가진 스프링 컨테이너가 서블릿 컨테이너 뒤쪽에서

  서블릿을 통해 웹으로 들어온 요청을 받아 스프링 컨테이너한테 다시 넘겨줌

- 스프링 컨테이너가 '어느 Bean이 요청을 처리해라'

- 그러면 하나의 Bean이 '내가 작업하는 동안 ~~ 기능이 필요하니까 네가 이 작업을 해달라'

- 스프링 컨테이너 안에서 우리가 만든 애플리케이션이 동작

✅ 대체 불가

  • 기본적으로 자바의 표준 웹 기술을 사용하려면 서블릿 컨테이너가 존재해야한다
  • 문제는 우리는 스프링으로 애플리케이션을 개발하는 것에만 집중해서 Bean들을 어떻게 구성할 것이고, 스프링 컨테이너에 어떻게 담을것인지 등을 고민하고 개발하면 좋을텐데
  • 동작을 시키려면 (가장 간단한 서버 프로그램 하나라도 띄우려면) 서블릿 컨테이너가 무조건 떠야 한다
  • 하지만 서블릿 컨테이너를 띄우는 것이 간단하지 않다
    • 오래된 기술
    • 많은 것을 포용하려고 다양한 설정 방법들을 요구함

✅ Web.xml

출처: 인프런-토비의 스프링부트

- 스프링 프로젝트를 만들려면 프로젝트에 웹.xml을 작성

     - 루트 컨텍스트, 디스패처 서블릿 등록, 서블릿 맵핑, 컨텍스트 로더 리스너 ...

- 이것이 들어가야지 Survlet Container가 뜨고 Survlet Container를 통해서 Spring Container가 호출되는 것

- XML은 복잡하다, 심지어 처음 프로젝트 셋업할 때 이외에는 거의 들여다 보지도 않는다

✅ .war

  • Spring Container를 포함한 Survlet Container 위에 돌아가는 애플리케이션은 확장자가 .war
    • 웹 애플리케이션 아카이브
    • .war로 빌드되어야 한다
  • 빌드 한다 → 빌드 툴 플러그인 사용?
  • 더 중요한건 폴더 구조
    • web-inf 밑에 클래스는 어디다 집어넣고, jar라이브러리는 어디다 집어 넣고,,

✅ 그외...

  • Survlet Container는 완전히 독립적인 서버 프로그램
  • Tomcat 같은 것을 받아 우리 환경에 맞게 설치하고 실행시켜야함
  • war 파일로 압축돼있는 Survlet 애플리케이션을 거기다 배포
    • 배포하는 방식도 다양
  • 충돌날 시 문제 해결할 줄 알아야함
  • Survlet Container에 설정할 것 多
    • 포트, 클래스로더
    • Survlet Container에 일어나는 로그 등 로깅과 관련된 것
  • 단순한 스프링 컨테이너에 들어간 애플리케이션을 만들기 위해, 설치하고 실행하기 위해서는
    • 꼭 필요하지만 중요하진 않은, 개발할 동안 신경써야되는 게 아닌 많은 정보들을 알고 있어야함
  • Survlet Container는 하나만 있는 게 아니다
    • Survlet Container는 표준 스펙
    • 그것을 구현한 제품을 갖다 사용해야함
      • Tomcat 등...
    • 만약 서로 다른 Survlet Container를 사용할 경우 (web.xml과 .war 파일 형식 말고) 그 외에 설치, 배포 방식 서버 컨테이너의 여러 설정 방법등을 새로 배워야 한다
  • 이때문에 진입 장벽이 높아짐
  • 학습 곡선이 높은데 그에 비해 유용하지 않다

👉🏻 Containerless Web Architecher

  • Survlet Container가 없는 컨테이너리스 웹 아키텍처를 만들었으면 좋겠다
  • ≠ Survlet Container를 사용하지 않고 어떻게 Spring Container가 웹 요청을 바로 받을 수 있을까
  • Survlet Container가 필요는 하지만 이것을 설치하고 관리하고 신경쓰기 위해 개발자가 뭔가 시간을 들이고 지식을 학습하고 적용하는 류의 수고 없이 할 수 있으면 좋겠다

- 실제로는 Survlet Container가 동작을 함

- 거기에 web.xml(혹은 그에 대응되는 java코드) 등이 알아서 Spring boot를 통해서 제공됨

- 그에 대한 설정을 하나도 신경쓰지 않고 일단 개발을 시작하고 서버를 띄우고 동작할 수 있다

✅ 독립 실행형 애플리케이션 (Stand Alone Application)

  • Survlet Container → 설치, 실행 필요
    • 아무리 다른 작업들은 디폴트 설정을 넣어 자동으로 한다 치더라도 Survlet Container가 시작은 해야됨
  • 이것을 띄우는 작업 필요? NO. 이것 마저도 제거
  • Spring Boot를 이용시 어떤 클래스의 메인 메소드를 호출하면 이 전체가 다 동작하는 방식으로 개발 가능
  • Spring Boot는 항상 메인 메소드가 나온다
    • 여기서 처음 시작되는구나를 볼 수 있다
  • 이것만으로도 Survlet Container와 관련된 모든 필요한 작업들이 다 수행이 되는 것

👉🏻 Opinionated

  • 자신의 의견을 굉장히 강하게 고집하는
  • 독선적인 주장이 강한
내가 다 정해줄게 일단 개발만 해

 

  • 프로젝트 시작하기 전에 고민 많이 하지 마
  • 내가 다 정해줄게
  • 너는 그저 고객한테 가치를 주기 위해서 필요로하는 이 소프트웨어의 도메인, 거기에 충실한 기능을 개발해

🧩 스프링 프레임워크의 설계 철학

✅ 극단적인 유연함 추구

  • 그 전에 나왔던 경직된 EJB 같은 기술과 달리
  • 유연하게 모든 걸 포용할 수 있음
  • 다양한 기술을 교체해가면서 사용할 수 있지만 네가 만든 애플리케이션 코드는 영향을 받지 않음
  • 추상화된 서비스를 통해 다양한 구현체에 일관된 방식으로 접근하거나
  • 이걸 테스트에서 사용하게 하기 위해 / 운용 환경에서 다른 목적으로 사용하기 위해 유연한 접근 방법 추구

✅ 다양한 관점을 수용

  • 다양한 종류의 기술의 관점을 수용
  • 표준 기술, 상용 기술, 오픈소스 기술
  • 같은 목적을 위해 만들어진 기술인데도 다양한 종류의 제품들이 많이 있는게 자바 생태계의 특징
    • 이 특징(장점)들을 모두 수용하겠다 = 스프링의 기본 태도

✅ Not opinionated

  • 위와 이어지는 내용
  • 스프링 레퍼런스 매뉴얼 앞부분에 스프링 부트와 달리 Not opinionated라는 표현이 나온다
  • 스프링 부트는 자신들의 주장을 강하게 고집하지 않는다
    • 사용자들이 원하는 다양한 선택지를 다 포용하겠다

✅ 수많은 선택지를 다 포용

✅ 하지만...

  • 대신 그것들을 선택하는 고민을 스프링 프레임워크를 사용하는 개발자들이 직접해야 한다
  • 새로운 스프링 프레임워크 프로젝트를 시작할 때 많은 시간들 들여 어떤 기술을 어떻게 사용할지 고민하는 시간이 필요
    • 이것을 잘 못하면 나중에 불편한 상황이 초래될 수 있다
    • 호환 문제, 기술 접근 방법 문제

🧩 스프링 부트의 설계 철학

✅ Opinionatated - 자기 주장이 강한, 자기 의견을 고집하는, 독선적인

  • 우리는 우리의 의견이 있고 그것을 고집하겠다
  • 너희가 여기에 따라야해

✅ 일단 정해주는대로 빠르게 개발하고 고민은 나중에

  • 우리가 기술적인 고민을 하지 않도록 정해줄테니
  • 너희는 일단 애플리케이션을 빠르게 개발하라

✅ 스프링을 잘 활용하는 뛰어난 방법을 제공

  • 스프링과 관련된 기술을 사용하는 수많은 방법 중 Best Practice를 제안하겠다. 거기서 출발해서 개발을 해봐라

빠르게 시작하면서도 광범위한 스프링 관련 기술들을 다 포용

🧩 사용 기술과 의존 라이브러리 결정

✅ 업계에서 검증된 스프링 생태계 프로젝트, 표준 자바 기술, 오픈소스 기술의 종류와 의존관계, 사용 버전을 정해준다

  • 우리가 만들고자 하는 애플리케이션에서 사용할 기술이 어떤 것인가
  • 어떤 라이브러리를 사용할 것인가
  • 어떤 버전을 사용할 것인가
  • 단순하게 JPA 사용하고 웹 사용할건데.. 라고 해도 그 안에 굉장히 많은 선택지가 있다
  • 똑같은 기술을 제공하는 기술이더라도 다양한 종류의 구현체가 있고, 각각의 장단점과 특징이 있다
  • 이렇게 여러가지 선택지 중 Spring Boot 개발팀이 굉장히 많은 시간동안 고민하고 검증을 거쳐 제안해준 표준 구성이 있다
    • 예를 들어 JPL을 사용한다면, 엔진, 라이브러리, 의존 라이브러리 등의 구성들을 기본적으로 다 만들어 제공
더보기
출처: 인프런-토비의 스프링 부트

Spring 3.0 시절 강사님이 만드신

Spring Core Framework 안에 들어있는 각 모듈들이 실제로 사용하고 있는 라이브러리들이 어떤 것이 있고 버전이 얼마인가,

필수인가 아니면 런타임시에만 사용되는건가

어떤 기능을 사용하면 이 라이브러리까지 필요하다 등의 내용을 표로 정리한 것

스프링 프레임워크 하나만 사용해도 이정도의 기술 분석이 필요하다

어떤 기술을 사용해야될지에 대해 면밀히 따져봐야함

게다가 Core Framework와 다른 생태계 프로젝트들까지 고려하면 이보다 훨씬 더 많고 복잡하다

 

 

✅ 각 기술을 스프링에 적용하는 방식(DI 구성)과 디폴트 설정값 제공

  • 라이브러리를 결정해도 DI구성, Bean을 기본적으로 설정하는 방식, 거기 들어가는 디폴트 설정값들이 필요한데 이런 부분까지 Spring Boot가 어느정도 제공을 한다
  • 꼭 개발자가 결정하고 넘어가도록 비워 둔 것도 있긴 함
더보기
출처: 인프런-토비의 스프링 부트

XML로 된 레퍼런스 샘플

데이터 소스를 아파치의 Basic Data Source라는 커넥션 풀을 사용하겠다 하면

거기에 설정할 기본 속성들이 4개가 있고

우리 상황에 맞게 면밀하게 적용하기 위한 설정, 항목들이 많이 있다

이 중 어떤 것들을 애플리케이션의 기본 속성으로 잡을 것인가

Hibernate5 사용 예제 - 속성값, 트랜젝션 매니저 등 호환되는 것을 설정해줘야..

스프링 부트는 여기까지도 기본 작업을 다 해준다

DB 연결 정보 정도만 우리가 세팅하면 바로 애플리케이션 웹과 데이터베이스 API등을 사용하는 개발이 가능하도록 만들어짐

= 스프링 부트가 많은 것을 결정해주기 때문에

  • 자동으로 설정해주는 것의 문제 = 좀 더 고급스럽게, 확장시키려고 하거나 커스터마이징을 하려고 하면 매우 힘들다
    • 프레임워크를 뜯어 고쳐야한다, 고치는 순간 장점들이 사라진다, 코어 기술 자체를 업그레이드하면 호환성이 깨진다

🧩 유연한 확장

✅ 스프링 부트에 내장된 디폴트 구성을 커스터마이징하는 매우 자연스럽고 유연한 방법 제공

  • 사용자가 고치고 싶은 부분이 생기면 그 부분만 변경할 수 있게 
  • 영리한 방법 제공
  • 유연

✅ 스프링 부트가 스프링을 사용하는 방식을 이해한다면 언제라도 스프링 부트를 제거하고 원하는 방식으로 재구성 가능

  • 우리가 만든 애플리케이션 코드를 거의 건들지 않은 채로 모두 조금씩 제거(=설정 또는 기본 동작을 조금씩 바꾸거나 비활성화??)하고 모든 것을 명시적으로 (우리가 지정하는 방식으로) 재구성할 수 있다

✅ 스프링 부트처럼 기술과 구성을 간편하게 제공하는 나만의 모듈 작성

  • 우리가 만든 모듈도 Spring Boot가 제공하는 모듈처럼 기술과 구성을 미리 지정해두고 간편하게 확장할 수 있게도 해줌
  • 나만의 Spring Boot 모듈 만들기가 가능

👉🏻 스프링 부트의 이해

🧩 스프링 부트를 이용한 개발 방법

✅ 부트가 결정한 기술과 구성, 디폴트 설정을 수용

  • 이를 통해 애플리케이션 코드에만 집중해서 개발을 빠르게 시작

✅ 외부 설정 파일을 이용한 설정 변경 방법을 활용

  • 필요한 경우에

✅ 아주 빠르게 개발을 시작할 수 있다

✅ 하지만...

  • 어느 단계에서는 한계 / 어려움에 직면할 수 있다

🧩 스프링 부트를 이용한 개발의 오해와 한계

✅ 애플리케이션 기능 코드만 잘 작성하면 된다?

  • 처음엔 맞는 얘기일 수 있지만 여기서 그치면 안돼

✅ 스프링을 몰라도 개발을 잘 할 수 있다?

✅ 스프링 부트가 직접적으로 보여주지 않는 것은 몰라도 된다?

  • 부트가 코드를 생성해 놓고 이 코드를 가지고 개발? 그런식으로 접근하지 않는다
  • 보이지 않는 곳에서 동작하는데 우리에게 보여주지 않는 부분에 대해서 알 필요가 없다 생각하는 것도 오해다

✅ 뭔가 기술적인 필요가 생기면 검색을 해서 해결한다?

 

🧩 스프링 부트를 이해하게 되면

✅ 스프링 부트가 스프링의 기술을 어떻게 활용하는지 배우고 응용할 수 있다

  • 애플리케이션을 만들 때 스프링을 사용해야 한다.
  • 이때 스프링 부트가 스프링을 활용하는 방법을 통해 배울 수 있다

✅ 스프링 부트가 선택한 기술, 자동으로 만들어주는 구성, 디폴트 설정이 어떤 것인지 확인할 수 있다

  • 이미 적용/결정한 기술적 결정 사항들을 확인하는 것이 필요한 때가 있다
  • 어떤 기술 사용, 무엇을 자동으로 만들어주는지, 어떻게 구성하는지, 디폴트 설정 값은 어떤 것인지, 설정 파일을 통해 수정할 수 있는 것은 무엇인지, 빈 설정을 직접적으로 추가 혹은 라이브러리를 추가해서 바꿀 수 있는 포인트는 무엇인지 ...

✅ 필요할 때 부트의 기본구성을 수정하거나, 확장할 수 있다

✅ 나만의 스프링 부트 모듈을 만들어 활용할 수 있다

프레임워크를 효과적으로 재사용하기 위해서는 프레임워크의 최종 모습 뿐만 아니라 현재의 모습을 띠게 되기까지 진화한 과정을 살펴 보는 것이 가장 효과적이다. 프레임워크의 진화 과정 속에는 프레임워크의 구성 원리 및 설계 원칙, 재사용 가능한 컨텍스트와 변경 가능성에 관련된 다양한 정보가 들어 있기 때문이다
- 조영호

 

 


✏️ 더 알아본 내용

💡 엔터프라이즈 애플리케이션

"엔터프라이즈 애플리케이션"이라는 용어는 기업이나 조직 내에서 사용되는 소프트웨어 애플리케이션을 나타냅니다. 이러한 애플리케이션은 조직의 다양한 부문 및 기능에 대한 업무 프로세스를 지원하고 효율적으로 관리하기 위해 설계되었습니다.

엔터프라이즈 애플리케이션은 다양한 기능을 포함할 수 있으며 종종 기업의 자원 관리, 고객 서비스, 인사 관리, 회계, 생산 관리, 공급망 관리 등과 관련된 업무 프로세스를 자동화하고 통합하는 데 사용됩니다. 이러한 애플리케이션은 대규모 기업이나 조직에서 사용되며, 복잡한 비즈니스 환경에서 생산성을 향상시키고 의사 결정을 지원하는 데 도움이 됩니다.

대표적인 엔터프라이즈 애플리케이션에는 ERP (Enterprise Resource Planning), CRM (Customer Relationship Management), SCM (Supply Chain Management), HRM (Human Resource Management) 등이 포함됩니다. 이러한 시스템들은 종종 통합되어 조직 전체의 데이터 흐름을 관리하고 각 부문 간에 정보를 공유할 수 있도록 지원합니다.

 

 

💡 MVP

스프링 부트(Spring Boot)에서 "MVP"는 주로 Model-View-Presenter 패턴이 아니라, Model-View-Controller 패턴을 나타냅니다. 스프링 부트는 주로 MVC 아키텍처를 기반으로 하는데, 이는 소프트웨어를 모델(Model), 뷰(View), 컨트롤러(Controller) 세 가지 부분으로 나누어 개발하는 디자인 패턴입니다.

- Model (모델): 애플리케이션의 데이터 및 비즈니스 로직을 담당합니다. 스프링 부트에서는 이를 Java 객체 또는 데이터베이스와 관련된 작업을 수행하는 서비스로 구현할 수 있습니다.

- View (뷰): 사용자에게 보여지는 부분으로, 사용자 인터페이스를 나타냅니다. 스프링 부트에서는 주로 HTML 템플릿, Thymeleaf, 또는 다른 뷰 기술을 사용하여 구현할 수 있습니다.

- Controller (컨트롤러): 모델과 뷰 간의 상호 작용을 관리하며, 클라이언트의 요청을 처리하고 응답을 생성합니다. 스프링 부트에서는 주로 `@Controller` 어노테이션을 사용하여 컨트롤러를 정의하고, 요청 매핑과 같은 기능을 구현합니다.

그러므로, 스프링 부트의 "MVP"는 Model-View-Controller를 의미하며, 이는 웹 애플리케이션을 개발하는 데 사용되는 일반적인 아키텍처 패턴입니다.

 

 

💡 포조

스프링(Spring) 프레임워크에서 "포조(Fojo)"라는 용어는 기본적으로 스프링 빈(Bean)을 가리킵니다. "포조"는 한국 스프링 사용자 그룹에서 사용되는 용어로, 스프링의 핵심 개념 중 하나인 빈을 지칭합니다. 스펠링은 "Fojo"입니다.

스프링에서 빈은 애플리케이션의 핵심 구성 요소로서, 스프링 컨테이너에 의해 생성, 관리되는 객체를 의미합니다. 빈은 스프링의 IoC (Inversion of Control) 컨셉을 통해 애플리케이션의 제어 흐름이 개발자가 아닌 스프링 컨테이너에게 넘어가도록 하는 중요한 역할을 합니다. 빈은 일반적으로 XML 설정 파일이나 자바 어노테이션을 통해 정의되며, 스프링은 이를 관리하고 필요에 따라 생성하여 제공합니다.

 

💡 GA

"General Availability"의 약어로 사용되며, 제품이나 서비스가 일반적으로 사용 가능하고 판매 가능한 상태에 도달했을 때를 나타냅니다. 이것은 제품이 완전히 개발되었고, 테스트 단계를 마치고 일반 사용자들에게 제공될 수 있는 상태를 의미합니다. 때로는 "GA"가 "공식 출시"를 나타내기도 합니다.

 

💡 JPA

스프링 부트에서 JPA(Jakarta Persistence API)는 자바 기반의 ORM(Object-Relational Mapping) 프레임워크를 말합니다. ORM은 객체 지향 프로그래밍 언어에서의 객체와 관계형 데이터베이스 간의 매핑을 담당하는 기술이며, JPA는 이러한 매핑을 자동으로 처리해주는 표준 인터페이스를 제공합니다.

JPA의 주요 목적은 개발자가 SQL 쿼리를 직접 작성하지 않고 객체 지향 프로그래밍을 통해 데이터베이스를 다룰 수 있도록 도와줍니다. 스프링 부트에서 JPA를 사용하면 개발자는 객체를 데이터베이스에 저장하고 조회하는 등의 작업을 편리하게 수행할 수 있습니다.

JPA의 주요 특징과 개념은 다음과 같습니다:

1. Entity(엔터티): JPA에서는 데이터베이스의 테이블과 매핑되는 객체를 엔터티라고 부릅니다. 엔터티 클래스는 `@Entity` 어노테이션을 사용하여 정의하며, 데이터베이스의 레코드와 매핑됩니다.

@Entity
   public class User {
       @Id
       @GeneratedValue(strategy = GenerationType.IDENTITY)
       private Long id;

       private String username;
       private String email;

       // Getters and setters
   }



2. Repository(리포지토리): JPA에서는 엔터티의 CRUD(Create, Read, Update, Delete) 작업을 수행하는데 사용되는 Repository 인터페이스를 제공합니다. 스프링 부트에서는 인터페이스를 작성하고 `CrudRepository` 또는 `JpaRepository` 인터페이스를 상속받아 사용합니다.

public interface UserRepository extends JpaRepository<User, Long> {
       // 추가적인 메서드 정의 가능
       User findByUsername(String username);
   }



3. EntityManager: JPA에서는 엔터티 매니저를 통해 엔터티의 영속성을 관리합니다. 영속성 컨텍스트를 통해 엔터티 객체의 상태를 추적하고, 데이터베이스와의 동기화를 담당합니다.

@Autowired
   private EntityManager entityManager;

   public void saveUser(User user) {
       entityManager.persist(user);
   }

   public User findUserById(Long userId) {
       return entityManager.find(User.class, userId);
   }



4. JPQL(Java Persistence Query Language): SQL과 유사한 문법을 가진 객체 지향 쿼리 언어로, JPA에서 엔터티를 조회하는데 사용됩니다.

   TypedQuery<User> query = entityManager.createQuery("SELECT u FROM User u WHERE u.username = :username", User.class);
   query.setParameter("username", "john_doe");
   List<User> users = query.getResultList();


이렇게 JPA를 사용하면 개발자는 데이터베이스와의 상세한 상호작용 없이 객체 지향적인 코드를 작성할 수 있으며, JPA가 쿼리를 생성하고 실행하여 데이터베이스와 효율적으로 상호작용합니다. 스프링 부트에서는 JPA를 쉽게 설정하고 사용할 수 있도록 다양한 도구와 기능을 제공하므로, 개발자가 빠르게 개발할 수 있습니다.

 

💡 DI 구성

DI(의존성 주입)는 객체 지향 프로그래밍에서 사용되는 설계 원칙 중 하나로, 객체 간의 의존성을 외부에서 주입하도록 하는 디자인 패턴입니다. DI를 통해 객체 간의 결합도를 낮추고 유연성을 향상시킬 수 있습니다.
DI는 주로 다음 두 가지 방식으로 구현됩니다:
1. 생성자 주입(Constructor Injection): 객체를 생성할 때 해당 객체의 생성자를 통해 의존성을 주입하는 방식입니다. 이는 주로 필수적인 의존성을 가진 객체를 생성할 때 사용됩니다.

public class Car {
        private Engine engine;

        // 생성자 주입
        public Car(Engine engine) {
            this.engine = engine;
        }

        // 다른 메서드들...
    }



2. 세터 주입(Setter Injection): 객체의 세터 메서드를 통해 의존성을 주입하는 방식입니다. 이는 주로 선택적인 의존성을 가진 객체를 설정할 때 사용됩니다.

public class Person {
        private Address address;

        // 세터 주입
        public void setAddress(Address address) {
            this.address = address;
        }

        // 다른 메서드들...
    }



DI를 사용하면 객체 간의 결합이 줄어들어 코드의 재사용성과 유지보수성이 향상되며, 테스트도 보다 쉬워집니다. 또한, 의존성 주입을 통해 객체를 쉽게 교체하거나 확장할 수 있어 시스템의 확장성을 높일 수 있습니다.
스프링 프레임워크에서는 DI를 기반으로 하는 IoC(Inversion of Control) 컨테이너를 제공합니다. IoC 컨테이너는 애플리케이션의 컴포넌트(빈)들을 관리하고, 필요한 의존성을 주입하여 객체의 생명주기를 관리합니다. 스프링에서는 주로 XML 또는 JavaConfig와 같은 설정을 사용하여 의존성 주입을 설정하고, 애플리케이션 컨텍스트를 통해 빈들을 관리합니다.
간단한 스프링에서의 빈 구성 예시는 다음과 같습니다:

@Configuration
public class AppConfig {

    @Bean
    public Engine engine() {
        return new Engine();
    }

    @Bean
    public Car car(Engine engine) {
        return new Car(engine);
    }
}


이렇게 하면 스프링 IoC 컨테이너가 `Engine`와 `Car` 객체를 생성하고, `Car` 객체를 생성할 때 `Engine` 객체를 주입합니다. 이를 통해 의존성 주입을 효과적으로 수행할 수 있습니다.

 

💡Hibernate

Hibernate는 자바 기반의 오픈 소스 ORM(객체 관계 매핑) 프레임워크입니다. ORM은 객체 지향 프로그래밍 언어에서 데이터베이스를 사용할 때 객체와 데이터베이스 간의 매핑을 자동으로 처리해주는 기술을 말합니다.

Hibernate는 관계형 데이터베이스와 객체 간의 매핑을 편리하게 처리하고자 하는 목적으로 개발되었습니다. 이를 통해 개발자는 객체 지향 프로그래밍에서 사용되는 클래스와 관계를 데이터베이스 테이블과 매핑할 수 있습니다. 이렇게 하면 데이터베이스 조작이 객체 지향 코드로 추상화되어 개발자가 SQL 쿼리를 직접 작성하지 않아도 됩니다.

스프링 부트에서는 Hibernate를 포함하여 JPA(Java Persistence API)를 통해 데이터베이스와의 상호 작용을 단순화하고 개발자들이 더 효율적으로 데이터를 다룰 수 있도록 지원합니다. 스프링 부트에서는 XML 설정 뿐만 아니라 Java Config를 사용하여 Hibernate를 통한 데이터베이스 액세스를 설정할 수 있습니다.

스프링 부트가 제공하는 편리한 기능과 함께 Hibernate를 사용하면 데이터베이스와의 상호 작용이 간편해지며, 개발자는 더 높은 수준에서 비즈니스 로직에 집중할 수 있습니다.

 

💡 트랜젝션 매니저

트랜잭션 매니저는 데이터베이스 트랜잭션을 관리하는 역할을 하는 컴포넌트입니다. 트랜잭션은 데이터베이스 상태를 일관성 있게 유지하기 위한 작업의 논리적 단위를 나타내며, 성공적으로 완료되면 변경사항을 영구적으로 반영하고, 실패하면 이전 상태로 롤백하는 기능을 수행합니다.

트랜잭션 매니저는 다음과 같은 주요 역할을 수행합니다:

  1. 트랜잭션의 시작과 종료: 트랜잭션 매니저는 트랜잭션을 시작하고, 성공적으로 수행되면 커밋을 하여 변경사항을 영구적으로 적용하고, 실패하면 롤백하여 이전 상태로 되돌립니다.
  2. 트랜잭션 경계 설정: 트랜잭션 매니저는 어떤 작업이 트랜잭션의 범위 내에 속하는지를 결정하고, 트랜잭션 경계를 설정합니다. 이는 일반적으로 메소드나 어노테이션을 통해 구현됩니다.
  3. 동시성 제어: 여러 개의 트랜잭션이 동시에 발생할 때, 트랜잭션 매니저는 동시성 문제를 해결하고 데이터베이스 일관성을 보장합니다.
  4. 트랜잭션 롤백 및 커밋: 트랜잭션 매니저는 트랜잭션을 성공적으로 완료하면 커밋을 수행하고, 실패하면 롤백을 수행하여 이전 상태로 되돌립니다.

스프링 프레임워크에서는 PlatformTransactionManager 인터페이스를 사용하여 다양한 종류의 트랜잭션 매니저를 지원하고 있습니다. 이를 이용하여 데이터베이스 트랜잭션을 효과적으로 관리할 수 있습니다. 트랜잭션 매니저는 스프링의 AOP(Aspect-Oriented Programming)와 연동하여 트랜잭션 경계 설정과 동시성 제어를 투명하게 처리할 수 있도록 지원됩니다.