Spring Boot

Spring Boot - Lombok, MVC Pattern

sounglikane 2024. 9. 27. 11:34

1. Lombok

Lombok은 자바에서 반복적으로 작성되는 코드를 줄여주는 라이브러리입니다. 주로 게터(Getter), 세터(Setter), 생성자(Constructor), toString() 같은 메서드를 자동으로 생성해줍니다. 이를 통해 코드가 더 깔끔하고 유지보수가 쉬워집니다.

 

주요 Lombok 어노테이션(annotation)은 다음과 같습니다:

  • @Getter@Setter: 필드에 대한 게터와 세터 메서드를 자동으로 생성합니다.
  • @Data: 여러 어노테이션을 결합한 것으로, @Getter, @Setter, @ToString, @EqualsAndHashCode 등을 포함합니다.
  • @NoArgsConstructor, @AllArgsConstructor, @RequiredArgsConstructor: 각각 매개변수가 없는 생성자, 모든 필드를 포함한 생성자, 그리고 final 필드를 포함한 생성자를 자동으로 생성해줍니다.
  • @Builder: 빌더 패턴을 쉽게 사용할 수 있게 해주는 어노테이션으로, 매개변수가 많은 객체를 더 읽기 쉽게 구성할 수 있습니다.
  • @Slf4j: SLF4J를 사용해 로그 인스턴스(log)를 추가해줍니다. 수동으로 로그를 생성할 필요가 없습니다.

 

예시:

package com.sparta.springprepare;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;


@Getter
@Setter
@RequiredArgsConstructor
public class Memo {
    private final String username;
    private String contents;
}

class Main {
    public static void main(String[] args) {
        Memo memo = new Memo("Drogba");
        System.out.println(memo.getUsername());

    }
}

'Memo.java' Class의 내용

 

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.sparta.springprepare;

public class Memo {
    private final String username;
    private String contents;

    public String getUsername() {
        return this.username;
    }

    public String getContents() {
        return this.contents;
    }

    public void setContents(final String contents) {
        this.contents = contents;
    }

    public Memo(final String username) {
        this.username = username;
    }
}

build에서 생성된 'Memo.class'의 내용

 

주의: Lombok은 시간을 절약할 수 있지만, IDE에서의 지원이 필요하며(주로 IntelliJ나 Eclipse는 잘 지원함), 너무 복잡한 프로젝트에서는 디버깅이 어려울 수 있으니 주의가 필요합니다.

 

 

2. MVC (Model-View-Controller) Pattern

  • 정의: MVC는 애플리케이션을 세 가지 상호 연결된 컴포넌트로 분리하는 소프트웨어 아키텍처 패턴입니다.
    • Model(모델): 데이터와 비즈니스 로직을 관리합니다.
    • View(뷰): 데이터를 표시하는 사용자 인터페이스(UI)를 담당합니다.
    • Controller(컨트롤러): 사용자의 입력을 받고, 모델 또는 뷰를 업데이트합니다.
  • 목적: 각 컴포넌트를 독립적으로 개발, 테스트, 유지보수할 수 있도록 하여 애플리케이션의 복잡도를 낮추고 구조를 명확하게 합니다.

 

상호작용:

  • Controller는 Browser를 통해 사용자 입력을 받습니다.
  • ControllerModel을 업데이트합니다.
  • View는 업데이트된 Model을 반영해 사용자에게 보여줍니다.

 

3. Spring Framework의 MVC 구현

Spring MVC는 자바 웹 애플리케이션을 개발할 때 사용되는 스프링 프레임워크 내의 MVC 디자인 패턴 구현체입니다.

Spring MVC는 중앙에 있는 DispatcherServlet이 요청을 처리하기 위한 공유 알고리즘을 제공하는 Front Controller 패턴을 중심으로 설계되어 있으며 이 모델은 유연하고 다양한 워크 플로우를 지원합니다.

Spring 공식 문서에서 Spring MVC에 대한 설명으로 ‘DispatcherServlet이 중앙에서 HTTP 요청을 처리해주는데 이는 Front Controller 패턴으로 설계되어있다’라고 설명하고 있습니다.

  • 주요 구성 요소:
    • DispatcherServlet: 모든 HTTP 요청을 처리하고 적절한 핸들러(컨트롤러)로 위임하는 프론트 컨트롤러 역할을 합니다.
    • Controller: 사용자의 요청을 처리하고, 모델과 상호작용하여 뷰를 반환합니다.
    • ModelAndView: 컨트롤러가 모델 데이터와 뷰 정보를 전달하기 위해 사용하는 객체입니다.
    • ViewResolver: 반환할 뷰(JSP, Thymeleaf 등)를 결정하는 역할을 합니다.
  • 작동 방식:
    1. 요청DispatcherServlet으로 전달
    2. DispatcherServletController로 요청을 전달
    3. ControllerModel을 업데이트
    4. ControllerViewResolver로 어떤 뷰를 반환할지 결정
    5. DispatcherServlet응답 (모델과 뷰를 합쳐 사용자에게 전달)

Servlet(서블릿)은 자바를 사용하여 웹 페이지를 동적으로 생성하는 서버 측 프로그램 혹은 그 사양을 말합니다.

  1. 사용자가 Client(브라우저)를 통해 서버에 HTTP Request 즉, API 요청을 합니다.
  2. 요청을 받은 Servlet 컨테이너는 HttpServletRequest, HttpServletResponse 객체를 생성합니다. 약속된 HTTP의 규격을 맞추면서 쉽게 HTTP에 담긴 데이터를 사용하기 위한 객체입니다.
  3. 설정된 정보를 통해 어떠한 Servlet에 대한 요청인지 찾습니다.
  4. 해당 Servlet에서 service 메서드를 호출한 뒤 브라우저의 요청 Method에 따라 doGet 혹은 doPost 등의 메서드를 호출합니다.
  5. 호출한 메서드들의 결과를 그대로 반환하거나 동적 페이지를 생성한 뒤 HttpServletResponse 객체에 응답을 담아 Client(브라우저)에 반환합니다.
  6. 응답이 완료되면 생성한 HttpServletRequest, HttpServletResponse 객체를 소멸합니다.

   * Controller (How it works?)

- Static Page and Dynamic Page

 

4. Spring MVC의 DispatcherServlet

DispatcherServletSpring MVC의 핵심 구성 요소로, 모든 들어오는 HTTP 요청을 가로채고 적절한 핸들러(주로 컨트롤러)에 전달하는 Front Controller(프론트 컨트롤러) 역할을 합니다.

 

작동 방식:

  1. 클라이언트 요청: 사용자가 HTTP 요청을 보냅니다.
  2. DispatcherServlet: 요청을 가로채고 처리합니다.
  3. Handler Mapping: DispatcherServlet은 Handler Mapping을 통해 적절한 컨트롤러를 찾습니다. Handler mapping에는 API path 와 Controller 메서드가 매칭되어 있습니다.
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    public HelloController() {
    }

    @GetMapping({"/api/hello"})
    public String hello() {
        return "Hello World";
    }
}

 

4. Controller: 선택된 컨트롤러는 요청을 처리하고, Model과 상호작용하여 데이터를 가져오거나 업데이트합니다.

5. View Resolver: 컨트롤러가 처리를 마친 후, View Resolver가 어떤 뷰를 렌더링할지 결정합니다.

6.View: 최종 뷰가 사용자에게 표시되며, 보통 모델에서 가져온 데이터를 포함한 동적 콘텐츠가 반영됩니다.

 

 

핵심 구성 요소:

  • 프론트 컨트롤러 패턴: DispatcherServlet은 프론트 컨트롤러 패턴을 따르며, 하나의 중앙 서블릿이 모든 HTTP 요청을 처리하고 적절한 컨트롤러로 위임합니다.
  • Model과 View: 컨트롤러는 일반적으로 모델 데이터와 뷰 정보를 포함한 ModelAndView 객체를 반환합니다.
  • Handler Mapping: URL, HTTP 메서드 등과 같은 정보를 바탕으로 적절한 컨트롤러 메서드를 매핑합니다.
  • View Resolver: JSP 파일 또는 Thymeleaf 템플릿과 같은 뷰를 결정하여 최종적으로 사용자에게 응답을 전달합니다.

 

Controller Code

@Controller
public class HelloController {
    @GetMapping("/api/hello")
    @ResponseBody
    public String hello() {
        return "Hello World!";
    }
}

 

Controller 주요의 HTTP Methods

package com.sparta.springmvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping("/api")
public class HelloController {
    @GetMapping ("/hello")
    @ResponseBody
    public String hello() {
        return "Hello Spring Boot!";
    }

    @GetMapping ("/get")
    @ResponseBody
    public String get() {
        return "GET Method 요청";
    }

    @PostMapping ("/post")
    @ResponseBody
    public String post() {
        return "POST Method 요청";
    }

    @PutMapping ("/put")
    @ResponseBody
    public String put() {
        return "PUT Method 요청";
    }

    @DeleteMapping ("/delete")
    @ResponseBody
    public String delete() {
        return "DELETE Method 요청";
    }
}