TIL-Spring 기초 3주차 (25.03.18)

kb·2025년 3월 18일

Spring

목록 보기
3/21

3주차 (7강/7강)

  • MVC 패턴
    • Template Engine ... 동적인 웹 페이지를 생성하기 위해 사용되는 도구. 템플릿을 기반으로 정적인 부분과 동적인 데이터를 결합하여 HTML, XML 등의 문서를 생성 -> 흔히 말하는 UI를 만들며, SSR에 사용. / 자바코드로 HTML을 만드는 것이 아닌, HTML 문서에 동적으로 변경해야 하는 부분만 자바 코드를 넣을 수 있어 더 편리. Thymeleaf, JSP가 대표적
    • MVC ... Servlet이나 JSP만으로 비즈니스 로직과 View Rendering까지 모두 처리하면 너무 많은 역할을 하게 되고 유지보수가 굉장히 어려워져(책임이 너무 많음) 고안된 패턴. Web Application은 일반적으로 MVC(Model View Controller) 패턴을 사용
    • MVC 패턴 ... 하나의 Servlet이나 JSP로 처리하던 것들을 Model, View, Controller 영역으로 나눈 것 / View가 분리된 이유의 핵심은 변경임. 기획이 변하지 않는 이상 비즈니스 로직과 View의 수정 원인은 별개로 발생함. -> 화면 구성에 수정이 발생하면 View만 변경 / 요구사항에 수정이 발생하면 비즈니스 로직 변경. 즉, 서로 연관이 없는 코드끼리 함께 존재할 필요가 없다! 완전히 분리하자! model: View에 출력할 Data를 저장하는 객체. View는 비즈니스 로직이나 Data 접근을 몰라도 되고 View Rendering에만 집중하면 됨(책임 분리) // View: Model 객체에 담겨 있는 Data를 사용해 화면을 Rendering.
    • MVC 패턴의 문제점 ... View와 Model은 분리했지만, Controller는 여전히 문제가 있다. 공통 기능이 추가될수록 Controller에서 처리해야 하는 부분이 많아짐.(중복 호출)
    • 프론트 컨트롤러 패턴 ... Servelt(Controller)이 호출되기 전에 공통 기능을 하나의 Servlet에서 처리해주는 패턴. 프론트 컨트롤러(Servelt) 하나에 모든 클라이언트 요청이 들어옴. -> 입구가 오직 하나. 프론트 컨트로러(Servlet)에서 공통 기능을 처리하면 됨.! => 모든 요청을 하나의 프론트 컨트롤러가 받아, 공통 기능을 처리함. 요청을 처리할 수 있는 Controller를 찾아서 호출(Controller Mapping). 프론트 컨트롤러를 제외한 나머지 컨트롤러는 Servlet을 사용하지 않아도 됨.
    • 어댑터 패턴 ... 다양한 컨트롤러(Handler)를 유연하게 만들기 위해 도입됨. 컨트롤러들은 동일한 인터페이스를 구현하도록 하고 해당 인터페이스와 공통 로직 사이에 어댑터를 두어 유연하게 만듦. 서로 다른 인터페이스를 갖는 두 클래스를 연결해주는 패턴. -> 프론트 컨트롤러, 어댑터, 핸들러 모두 각자의 역할만 수행(책임 분리) -> 새로운 컨트롤러(Handler)가 추가되어도 컨트롤러와 어댑터만 추가하면 공통 로직 변경X
  • Spring MVC
    • Spring MVC 구조 ... MVC 패턴에 프론트 컨트롤러, 어댑터 패턴이 적용된 구조를 가짐. Dispatcher Servlet(프론트 컨트롤러), Handler Adapter(어댑터 패턴), Handler(컨트롤러)가 각자의 역할을 수행하도록 결합된 구조.
    • Dispatcher Servlet ... MVC의 프론트 컨트롤러는 Dispatcher Servlet(Servlet의 한 종류)임. Spring MVC의 핵심 기능!
    • Spring MVC의 주요 Interface ... Spring MVC는 DispatcherServlet 코드의 변경 없이 기능변경 및 확장이 가능. 기능들이 대부분 Interface로 만들어져 있기 때문. 인터페이스를 implements하여 구현하면 내가 만든 클래스를 사용할 수 있음. 1. HandlerMapping / 2. HandlerAdapter / 3. ViewResolver / 4. View -> Spring Framework의 모든 내부구조를 알 필요는 없음. 다만, 전체적인 동작 방식을 알면 좋음. 그래야 어떤 부분에서 문제가 발생했는지 파악할 수 있고, 구현하고자 하는 기능이 어떤 인터페이스에서 확장해야 하는지 파악할 수 있으니.
    • Controller Interface ... Spring Boot를 사용하면 이미 개발에 필요한 HandlerMapping과 HandlerAdapter가 대부분 구현되어 있어서 개발자가 직접 HandlerMapping과 HandlerAdapter를 구현하는 일은 거의 없다고!
    • Spring Boot의 Handler Mapping, Handler Adapter ... Spring Boot를 사용하면 개발에 필요하여 자동으로 등록되는 HandlerMapping과 HandlerAdapter들이 있음. 둘 다 우선순위대로 조회함.
      • HandlerMapping (우선순위) 1. RequestMappingHandlerMapping 2. BeanNameUrlHandlerMapping
      • HandlerAdapter (우선순위) 1. RequestMappingHandlerAdapter 2. HttpRequestHandler 3. SimpleControllerHandlerAdapter
    • HttpRequestHandler로 알아보는 Spring MVC 동작 순서 ... 기존 방식에서 사용하는 Servlet과 가장 유사한 Handler임.
      • 1) HandlerMapping으로 핸들러 조회 (a. BeanName으로 Handler 조회(HeanNameUrHandlerMapping 실행), b. ExampleRequestHandler 반환)
      • 2) HandlerAdapter 조회 (a. HandlerAdapter의 supports()를 우선순위 순서대로 호출, b. HttpRequestHandlerAdapter가 HttpReqeustHandler Interface를 지원)
      • 3) HandlerAdapter 실행 (a. DispatcherServlet이 조회한 HttpRequestHandler Adapter를 실행하며 Handler 정보도 넘김, b. HttpRequestHandlerAdapter는 ExampleRequestHandler를 내부에서 실행 후 결과를 반환)
    • View Resolver ... 반환된 ModelAndView 객체를 알맞은 View로 전달하기 위해 DispatcherServlet에서 ViewResolver를 호출하여 View 정보를 설정하는 역할 수행
    • Spring Boot의 ViewResolver ... 1. BeanNameViewResolver (a. Bean Name으로 View를 찾아 반환) 2. InternalResourceViewResolver (위 예시코드) (a. application.properties 설정 파일에 등록한 prefix, suffix 설정 정보를 사용하여 ViewResolver 등록
    • InternalResourceViewResolver ... application.properties 설정 파일에 등록한 prefix, suffix 설정 정보를 사용하는 ViewResolver. 실행 순서는 아래와 같음.
        1. HandlerAdapter 호출 : HandlerAdapter를 통해 "test" 논리 View Name 얻음
        1. ViewResolver 호출 : "test"이라는 View Name으로 viewResolver를 우선순위대로 호출 -> BeanNameViewResolver는 View를 찾지 못함 / InternalResourceViewResolver 호출
        1. InternalResourceViewResolver : InternalResourceViewResolver.buildView(String viewName) -> InternalResourceView 반환
        1. InternalResourceView : JSP와 같이 서버에서 이동하는 forward()를 호출하는 경우와 같을 때 사용. renderMergedOutputModel() -> Model을 Request로 바꿈
        1. view.render() : 외부에서 view.render()를 호출 후 RequestDispatcher를 가져와 forward()함. -> 매우 복잡한 구조를 가지고 있으니 모두 찾아볼 필요가 없음
      • Thymeleaf는 View와 Resolver가 이미 존재함. 라이브러리 의존성만 추가해주면 SpringBoot가 모두 자동으로 해줌. 즉, return "viewName";만으로 View가 Rendering 됨!
profile
Experience

0개의 댓글