Spring이란 무엇인가 - 2

최혜성·2024년 2월 2일
0

그러면 스프링이랑 스프링부트는 뭔차이임?

스프링부트는 그냥 편한 스프링이라고 보면 되겠다.
보통 부트 이전 스프링 자료를 보면 xml에다 빈을 추가하고.. 그걸 singleton으로 할지 prototype으로 할지 정하고.. 그걸 어디에다 주입하고.. 이런 과정을 수작업으로 해야했다.

물론 현재 부트에서도 많이 사용하는 @Autowire등 어노테이션 기반으로 할 수 있는 기능도 있긴 했다. 주류가 아니였을뿐

그래서 xml로 일일히 작성할 필요 없이 클래스에 Annotation 딸깍하면 알아서 스프링이 빈으로 만들어주고 DI까지 알아서 해주니 얼마나 좋은가

  • Bean - 그냥 스프링에서 관리해줄 수 있는 하나의 객체라고 보면 쉽다.
    사용자가 정의한 클래스도 빈으로써 등록해주면 알아서 스프링 DI 컨테이너가 주입도 해주고 생성 소멸도 관리해준다.

그래서 스프링과 스프링 부트는 AutoConfiguration의 차이라고 보면 되겠다.
해줘~~~

그럼 DI랑 IOC, AOP 밖에 없으면 웹은 어캐 처리함?

웹은 이제 1편에서 설명한 모든 기능을 총집합해서 클래스를 잘 구성해놓고, 웹 호출에다 쓰는 방식이다.

들어가기전

웹을 구성하는 서버는 2가지 종류로 나눌 수 있다.

  • 웹 서버
  • 웹 '애플리케이션' 서버

뭔차이일까?

웹 서버는 말그대로 '정적'서버이다. 그냥 웹에서 접근할 수 있는 ftp로 봐도 무방하다. 서버가 호스팅하는 html, js등 미리 정의된 파일에 접근하여 처리할 수 있도록 구성되어 있는 서버이다.
따라서 사용자의 특정한 입력을 받아서 동적으로 파싱하고~ 하는 기능은 사실상 구현할 수 없다는게 학계의 점심이다

웹 애플리케이션 서버는 '동적'인 서버이다. 실제 호스팅 되는 html이나 js를 반환하는것 대신, 직접 Servlet이라는 핸들러 느낌의 클래스를 거쳐 유저의 요청이 처리되고 그 응답을 반환한다.

그래서 웹 서버는 Apache, 웹 애플리케이션 서버는 Apache Tomcat으로 구현된다.

근데 내가 가는 서버는 정적인 html인데 동적인 기능도 다 처리하던데?

요거는 쉽게 설명하자면 웹 애플리케이션 서버에서도 웹 서버의 기능을 처리해준다고 보면 되겠다.

동적으로 처리하는게 사실상 리소스를 많이 잡아먹는데, 단순하게 html 파일만 줘~ 했는데 풀코스로 모든 핸들러를 다 처리한다면 서버가 많이 힘들것이다.
그러니까 이제 저장되어 있는 html만 반환하고 다음 요청을 받을 수 있게 내부적으로 웹 서버의 기능또한 갖고 있다 보면 되겠다.

그래서 웹 애플리케이션 서버를 보통 스프링에선 WAS라고 부른다.

이제야 WAS를 봐주는구나?

스프링은 이제 IOC, DI등등의 집약체를 관리하는 BeanFactory가 있고, 구현체인 ApplicationContext가 있다.

이제 웹 호출은 내장 Tomcat이 돌아가면서 WAS의 기능을 하고, 각 요청을 처리하는 방식이다.

WAS의 개념은 그렇다 쳐도, 이제 Controller의 CRUD기능은 어떻게 호출되는걸까?

이는 Servlet 개념을 알고 있어야 되겠다.

Servlet

WAS는 여러개의 Servlet들이 모여있는 서블렛 컨테이너가 있고, 이걸 거쳐서 요청이 처리된다.

그러면 커스텀 Servlet을 만들면 요청을 내맘대로 처리 할 수 있겠네?
스프링은 기본 서블렛인 HttpServlet을 상속받은 DispatherServlet을 이용하여 실질적인 웹 요청을 처리한다.

Http로 들어온 요청은 HttpServlet의 각 메소드 (Get - doGet(), Post - doPost, Delete - doDelete ...)에 매핑되어 호출되는데, DispatcherServlet은 이 메소드를 override해서 각 요청에 맞게 컨트롤러를 호출한다.

컨트롤러는 어떻게 알고 얘가 처리해

스프링부트에서 컨트롤러 선언을 할때 @Controller Annotation을 보통 붙여준다. 그러면 Component Scan 과정을 통해 패키지를 쭉~ 돌면서 해당 어노테이션이 있을경우 DispatcherServlet의 Controller Handler로 넣어준다.

왜냐, Annotation을 넣어놨으니 스프링 빈으로 인식될거고, 이게 DispatcherServlet에게 DI 되는 과정이라서 그렇다.

이제 요청이 들어왔다.

  • HttpServlet을 상속받는 DispatcherServlet이 받아 처리한다.
  • Dispatcher Servlet이 각 요청에 맞게 override한 doX함수를 호출한다.
  • ViewResolve 과정 등등을 거치고 HandlerMapping보고 처리해달라 한다.
  • HandlerMapping은 Controller중에 처리할 수 있는 얘를 데려다준다.
  • 해당 컨트롤러가 멋지게 처리한다.
  • 결과값을 반환한다.
  • 이걸 자기가 한것처럼 Dispatcher Servlet이 반환한다.

그래서 이 과정을 통해 스프링의 대다수의 과정이 이루어진다고 보면 되겠다.

여담

https://mangkyu.tistory.com/225
스프링의 Dispatcher Servlet은 HttpServlet을 상속받는다고 했는데, 여기서 약간의 문제가 생겼다.
분명이 웹 요청에는 GET, POST, DELETE, PUT 요정도가 있어서 메소드는 요거를 만들어놨는데, 최근에 PATCH라는 요청이 만들어져 이게 추가될 필요가 있었다.

위에서 말했다시피 DispatcherServlet은 Http의 doX를 이용해서 각 요청을 처리한다고 했는데, 하필이면 doPatch가 구현되어 있지 않았다.

실제 요청을 처리할려면 HttpServlet에서 구현해줘야 하는데, 이게 공식 표준이라 해당 클래스를 수정할 수도 없어서 난감했다.

그래서 어떻게 했냐.
스프링 서블렛이 요청을 받고, 응답을 잘 파싱해서 Http서블렛의 doX함수를 호출하는데, 이 파싱과정에서 Patch가 들어왔으면 따로 처리할 수 있도록 분기를 나눴다.

결론은 잘 처리된다고 하는데, 아무리 확장성을 높게 잡고 잘 구현된 클래스라 하더라도 어쩔 수 없을때는 한번쯤은 있는것 같긴하다.

profile
KRW 채굴기

0개의 댓글