Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

이지은님의 블로그

250123 - Java Spring 기초: Spring MVC와 3-Layered Architecture(프론트 컨트롤러 패턴, 어댑터 패턴) 본문

TIL

250123 - Java Spring 기초: Spring MVC와 3-Layered Architecture(프론트 컨트롤러 패턴, 어댑터 패턴)

queenriwon3 2025. 1. 23. 23:05

 코드 문제풀이

[JAVA] 코드카타 - (51)~(55)

 

[JAVA] 코드카타 - (51)~(55)

문제 (51) : 푸드 파이트 대회수웅이는 매달 주어진 음식을 빨리 먹는 푸드 파이트 대회를 개최합니다. 이 대회에서 선수들은 1대 1로 대결하며, 매 대결마다 음식의 종류와 양이 바뀝니다. 대결

queenriwon3.tistory.com

 

 

▷ 오늘 배운 것

오늘은 Spring 기초 3주차 개념부분을 듣고 알게된 것을 정리하려고 한다.

 

 

<<목차>>

1. Spring Framework

2. Spring MVC

3. 3 Layered Architecture란?

4. MVC 패턴 응용

1) Template Engine

2) MVC 패턴을 코드에 응용

3) 프론트 컨트롤러 패턴

4) 어댑터 패턴

 

 


 

 

[TIL] 메모

 

 

1. Spring Framework

 

Spring 이란?

자바 기반의 애플리케이션 프레임워크이다.

  • 필요한 모듈만 선택적으로 사용이 가능하다. (lombok 등)
  • IoC 컨테이너와 DI를 통해 객체의 생성 및 의존성을 관리한다.
  • Spring Webflux, Spring Security 등 다양한 기술 스택을 지원한다.
  • JUnit이나 Mockito와 같은 다양한 테스트 환경을 지원한다.

 

Spring의 장점
  1. 복잡성 관리: 대규모 애플리케이션의 복잡성을 계층화
  2. 유지보수성: 코드 재사용성, 모듈화, 공통적인 조직을 Service계층에서 관리
  3. 생산성 증가: Spring Boot 사용 -> 애플리케이션을 신속히 초기화
                      REST API를 빠르게 구축하고 데이터베이스 연동을 간단히 처리

 

 

2. Spring MVC

 

Spring MVC란?

Model-View-Controller 디자인 패턴을 기반으로 한 웹 프레임워크

 

왜 MVC패턴을 사용해야 할까.

사용자가 보는 페이지, 데이터처리, 그리고 이 2가지를 중간에서 제어하는 컨트롤, 이 3가지로 구성되는 하나의 애플리케이션을 만들면 각각 맡은바에만 집중을 할 수 있게 된다.

 

디자인 패턴이란?

상황에 따라 간편하게 적용해서 쓸 수 있는 것을 정리하여 특정한 "규약"을 통해 쉽게 쓸 수 있는 형태로 만든 것

 

 

1️⃣ Model: 데이터 + 비즈니스 로직, 데이터 관리

 

Model 규칙
  1. 사용자가 편집하길 원하는 모든 데이터를 가지고 있어야 한다.
  2. 뷰나 컨트롤러에 대해서 어떤 정보도 알지 말아야 한다.
  3. 변경이 일어나면, 변경 통지에 대한 처리방법을 구현해야만 한다.
  4. 모델은 재사용가능해야 하며 다른 인터페이스에서도 변하지 않아야 합니다.

 

2️⃣ View: 사용자에게 보이는 화면, 데이터 시각화, 사용자의 입력을 컨트롤러에 전달

 

View 규칙
  1. 모델이 가지고 있는 정보를 따로 저장해서는 안된다.
  2. 모델이나 컨트롤러와 같이 다른 구성요소들을 몰라야 된다.
  3. 변경이 일어나면 변경통지에 대한 처리방법을 구현해야만 한다.
  4. 재사용가능하게끔 설계를 해야 하며 다른 정보들을 표현할 때 쉽게 설계를 해야 합니다.

 

3️⃣ Controller: 요청을 처리하고 Model과 View연결, 사용자 요청처리

 

Controller 규칙
  1. 모델이나 뷰에 대해서 알고 있어야 한다
  2. 모델이나 뷰의 변경을 모니터링 해야 한다.

 

 

ex) 유저의 프로필을 보여주는 서비스를 만들었다고 해보자, 위의 그림은 다음과 같이 진행된다

 

 

최근에는 서버와 클라이언트의 역할이 분리되어 백엔드와 프론트엔드로 나뉘었다.

그래서 서버와 클라이언트 간 데이터를 주고 받는 Restful API가 주류로 자리잡았다. 이전에는 View를 통해 직접 화면을 그려줬는데(Template Engine), 요즘엔 Json 형태로 프론트엔드에 데이터를 전달해준다.

렌더링 버전(템플릿 엔진) Restful API(Json 형태)
1️⃣ 사용자가 상품등록 버튼 클릭(요청) 1️⃣ 사용자가 Postman 같은 도구를 통해 "상품 등록" API 호출(요청)
2️⃣ Controller 요청을 받아 Model에게 상품등록 요청 2️⃣ Controller 요청을 받아 Model에게 상품등록 요청
3️⃣ Model 비즈니스 로직을 처리 + DB저장 3️⃣ Model 비즈니스 로직을 처리 + DB저장
4️⃣ View 화면 구성(응답) 4️⃣ Controller 결과를 JSON 형식으로 변환하여 반환 -> 프론트엔드와 통신

 

 

 

 

3. 3 Layered Architecture란?

애플리케이션의 컴포넌트를 유사 관심사를 기준으로 묶어 수평적으로 구성한 구조이다. 계층(Layer)을 묶고 나서 각 계층이 가장 가까운 하위 계층의 의존성을 주입받아 다른 계층과 통신하게 된다.

 

애플리케이션을 계층화하여 모듈화

각 계층간의 책임 분리가 되어 비즈니스 로직 서비스를 추가할경우 Service계층만 수정하면 다른 계층은 변경할 필요가 없다.

 

 

 

1️⃣ Presentation Layer: 클라이언트의 요청을 해석 및 응답 (Controller)

ex) 쇼핑몰에서 상품 상세 페이지를 사용자가 요청하면, Controller가 요청을 받아 Service에 전달하고 결과를 반환한다.

// Controller
@RestController
@RequestMapping("/products")
public class ProductController {
    private final ProductService productService;

    public ProductController(ProductService productService) {
        this.productService = productService;
    }

    @GetMapping("/{id}")
    public ResponseEntity<ProductDTO> getProduct(@PathVariable Long id) {
        ProductDTO product = productService.getProductById(id);
        return ResponseEntity.ok(product);
    }
}

 

 

2️⃣ Business Logic Layer: 애플리케이션의 핵심 로직 처리 (Service)

ex) 쇼핑몰에서 "할인 정책"을 계산하거나 "재고 확인" 로직을 처리하는 부분은 Service 계층에서 담당한다.

// Service
@Service
public class ProductService {
    private final ProductRepository productRepository;

    public ProductService(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }

    public ProductDTO getProductById(Long id) {
        Product product = productRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("Product not found"));
        return new ProductDTO(product.getId(), product.getName(), product.getPrice(), product.getStockQuantity());
    }
}

 

 

 

3️⃣ Data Access Layer: 데이터베이스와 상호작용 (Repository, Entity)

ex) 상품 정보나 사용자 정보를 데이터베이스에서 가져오거나 저장하는 작업을 Repository 계층에서 수행한다.

// Repository
@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {}


// Entity
@Entity
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private double price;
    private int stockQuantity;

    // Getters and Setters
}

 

 

DTO(Data Transfer Object): 프로세스 사이에서 데이터를 전송하는 객체(Json형태로 자동 전달)

// DTO
public class ProductDTO {
    private Long id;
    private String name;
    private double price;
    private int stockQuantity;

    public ProductDTO(Long id, String name, double price, int stockQuantity) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.stockQuantity = stockQuantity;
    }

    // Getters and Setters
}

 

 

MVC와 3Layered Architecture 차이
기준 MVC 3 Layered Architecture
초점 MVC 클라이언트와 서버간의 구조 관점에서 접근한 개념 Spring 3 Layer 서버 개발 관점에서 계층 별로 역할을 분리하는 개념
구성 요소 Model, View, Controller Presentation, Business Logic, Data Access
적용 범위 애플리케이션의 UI 계층 전체 애플리케이션 구조
Controller 역할 요청을 처리하고 Model View 연결 Presentation Layer 일부로 작동
데이터와 비즈니스 로직 Model 데이터와 로직 모두 담당 Business Logic Layer 비즈니스 로직 전담
Spring 주요 관점 사용자 요청 처리와 응답 생성 -> 서버와 상호작용 애플리케이션의 구조화 계층화 -> 유지보수성과 확장성

 

 

MVC계층 + 3Layered Architecture

1. 프레젠테이션 계층(Controller): HandlerMapping을 통해 Controller을 선택하여 요청을 전달

2. 비즈니스 로직 계층(Service): 비즈니스 로직을 처리한다. 

3. 데이터 접근 계층(DAO, Repository):  데이터 관련된 작업을 수행

 

최종적으로 요청이 처리된 데이터와 뷰를 선택하여 ModelAndView 객체가 DispatcherServlet 전달되면 ViewResolver 통해 클라이언트는 처리된 데이터를 통해 출력된 화면을 있다.

 

👉 Domain Object
- DTO(Data Transfer Object)는 다른 계층이나 컴포넌트로 데이터를 넘겨주기 위한 자료 구조이다.
- Entity는 실제 DB 테이블과 매핑되는 클래스이다.

 

// Entity : 실제 DB테이블과 매핑되는 클래스
@Entity
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private double price;
    private int stockQuantity;

    // Getters and Setters
}

// DTO : 다른 계층으로 데이터를 넘겨주는 구조
public class ProductDTO {
    private Long id;
    private String name;
    private double price;
    private int stockQuantity;

    public ProductDTO(Long id, String name, double price, int stockQuantity) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.stockQuantity = stockQuantity;
    }

    // Getters and Setters
}

 

 

 

4. MVC 패턴 응용

1) Template Engine

템플릿 엔진이란, 

동적인 웹 페이지를 생성하기 위해 사용되는 도구이며 템플릿을 기반으로 정적인 부분과 동적인 데이터를 결합하여 HTML, XML 등의 문서를 생성하는 역할을 수행한다. —> UI(User Interface)을 만들며 SSR(Server Side Rendering)에 사용

 

자바 코드로 HTML을 만들어 내는 것이 아닌 HTML 문서에 동적으로 변경해야하는 부분만 자바코드를 넣을 수 있어 편리하다.

 

대표적인 템플릿 엔진은 Thymeleaf(Spring과 통합), JSP(java Server Page), FreeMarker, Velocity, Mustache가 있다.

* JSP는 HTML 코드 상에 <% %>부분에 자바 코드를 작성함

 

Servlet은 화면에 그리는 View와 비즈니스 로직이 모두 섞여있기 때문에 책임 분리가 필요했다. 

 

  1. Servlet만을 사용한 경우 View를 위한 코드와 비지니스 로직을 처리하는 코드가 Servlet에 모두 존재하여 유지보수가 어려워진다.
  2. JSP를 사용하여 View를 분리하였지만 비지니스 로직의 일부가 JSP 파일안에 존재한다. 여전히 책임이 많아 유지보수가 어렵다.

이를 보완하기 위해 Web Application은 일반적으로 MVC(Model View Controller) 패턴을 사용한다.

 

 

2) MVC 패턴을 코드에 응용

1️⃣ Model : 출력할 데이터를 저장 + 비즈니스 로직 + 데이터 접근

2️⃣ View: Model에 담긴 데이터를 화면에 렌더링

3️⃣ Controller:

HTTP Request 를 전달받아 파라미터 검증, 비즈니스 로직을 포함할 수 있지만 Service Layer를 호출하는 역할, 데이터를 객체로 임시저장

(전반적으로 비즈니스 로직은 Service Layer에서 별도로 만들어 처리, 데이터와 상호작용하는 것은 Repository Layer를 구성)

 

 

MVC 패턴의 문제점
  1. dispatcher.forward(request, response) View로 이동하는 forward가 항상 중복 호출된다.
  2. String path= “/WEB-INF/views/new-form.jsp” View의 path를 입력(중복 작업)한다.
    jsp 파일의 경로 혹은 이름이 바뀌면 해당 코드가 변경되어야 한다.
    JSP 이외의 확장자를 사용하려면 전체가 변경되어야 한다.
  3. HttpServletResponse 객체를 사용하는 경우가 적다. (JSP에서 모두 해결하기 때문)
    HttpServletRequest와 HttpServletResponse는 Test 코드를 작성하기도 매우 힘들다.
  4. 공통 기능이 추가될수록 Controller에서 처리해야 하는 부분들이 많아진다.

 

 

3) 프론트 컨트롤러 패턴

프론트 컨트롤러 패턴이란?

Servlet(Controller)이 호출되기 전에 공통 기능을 하나의 Servlet에서 처리해주는 패턴

 

프론트 컨트롤러가 모든 요청을 받으며 공통 기능을 처리한다. 이후 요청을 처리할 수 있는 컨트롤러가 호출된다.(Controller Mapping)

그러나 Controller 마다 로직이나 응답해야하는 결과는 당연히 다를테고 응답을 동일하게 맞추려고 한다면 해당 애플리케이션은 확장성, 유지보수성을 잃는다.

 

이를 보완하기 위해 어댑터 패턴이 고안된다.

 

 

4) 어댑터 패턴

어댑터 패턴이란?

다양한 컨트롤러(핸들러)를 유연하게 만들기 위해 고안되었다. 컨트롤러들은 동일한 인터페이스를 구현하도록 하고 해당 인터페이스와 공통 로직 사이에 어댑터를 두어 유연하게 만든다. 서로 다른 인터페이스를 갖는 두 클래스를 연결해주는 패턴이다.

 

컨트롤러(핸들러)는 비즈니스 로직을 처리하고 알맞은 결과를 반환한다. 이후 어댑터가 공통로직과 컨트롤러가 자연스럽게 연결되도록한다. 프론트 컨트롤러는 공통으로 처리되는 로직을 수행한다.

 

이 모든게 적용된 것이 Spring MVC이다(프론트 컨트롤러 패턴, 어댑터 패턴이 모두 적용)

스프링 부트의 경우 보통 spring-boot-starter-web 의존성 사용하므로 기본적으로 스프링 MVC 구조를 띤다. 

 

 

▷ 참고 블로그

https://hello-jinny.tistory.com/15

 

Spring MVC 구조와 레이어드 아키텍처

Spring MVC & Layered Architecture이번에는 MVC 패턴과 레이어드 아키텍처를 통해 Spring의 기본적인 동작 방식을 알아보려고 한다. MVC와 Layered Architecture에 대한 내용을 각각 살펴보고, Spring에서의 동작 과

hello-jinny.tistory.com

 

https://m.blog.naver.com/jhc9639/220967034588

 

[개발자 면접준비]#1. MVC패턴이란

오늘은 개발자면접에 많이 나오기도 하는 MVC패턴에 대해서 알아보고자 합니다. 과연 MVC패턴이 무엇...

blog.naver.com