항해99

[항해99 TIL] MVC, DTO, IOC

Luke_look 2023. 6. 28. 23:31

1. Spring MVC란 무엇인가?

Spring MVC를 알기 전에 MVC 패턴를 알아야 합니다.

1) MVC패턴

Model-View-Controller의 줄임말로 어플리케이션을 구조화하는 방법입니다.

여기서 어플리케이션을 구조화하는 이유는 개발 과정에서 찾아볼 수 있는데 정리한다면

  1. **가독성** : 이해와 수정이 쉬움
  2. **재사용성** : 모듈화로 동일한 코드 사용 가능
  3. **유지보수** : 문제 발생시 보수하기 쉬움
  4. **확장성** : 기존 기능을 확장하기 쉬움
  5. **테스트 용이성** : 모듈화가 잘 되어 있으면 독립적인 테스트가 용이합니다.

그래서 구조화하는 방법 중 한가지인 MVC는 세가지로 분리하여 설계되어 있는데 **모델, 뷰, 컨트롤러**로 나누게 됩니다.

(1) 모델 (Model)

모델은 어플리케이션의 **정보나 데이터**를 표현합니다. 여기서 모델을 자세히 보게 되면 몇가지 역할로 나눌 수 있습니다.

  1. 데이터 엑세스 : 모델은 말그대로 데이터에 **추가** ,**접근**하고 **조작**하는 로직을 포함합니다.
  2. 비즈니스 로직 : 말이 요상시리 한데 **핵심 기능**을 말합니다. 쇼핑몰로 따지면 재고 관리, 계산, 주문 처리, 배송 처리 등이 있습니다.
  3. 데이터 유효성 : 데이터가 제대로 왔는지 보는 작업입니다. **데이터의 형식과 값**을 비교한다고 생각하시면 됩니다.
  4. 상태 관리 : 어플리케이션을 추적 관리하는 역할입니다. 예를 들면 로그인 상태, 진행중인 상태, 종료 상태 등을 말합니다.

(2) 뷰(View)

포장지라고 생각하면 편합니다. 시각적으로 표현해주고 모델의 데이터를 유저가 이해하기 쉬운 형태로 변환합니다.

뷰의 역할을 몇가지 나누었습니다.

  1. 데이터 표시 : 데이터를 사용자에게 표시하는 기능을 담당
  2. 사용자 인터랙션 : 버튼, 텍스트 입력 등 어플리케이션과의 상호 작용을 담당합니다.
  3. 사용자 피드백 : 유는 결국 뷰를 보고 사용하기 때문에 실제 상용화했을 때 피드백을 유저에게 얻습니다.

(3) 컨트롤러(Controller)

유저의 입력을 모델로 반영한다 생각하면 됩니다. 위에서 뷰가 상호작용 버튼을 누르면 컨트롤러가 적당한 모델을 찾아 실행합니다.

  1. 사용자 입력 처리 : 유저의 입력을 처리합니다. 뷰에서의 버튼이나 텍스트가 입력을 받아 작업을 수행합니다.
  2. 모델 변경 : 유저가 특정 데이터 수정을 하면 그에 맞게 모델의 상태를 변경합니다.
  3. 뷰 업데이트 : 모델입 변경되면 그에 맞는 변경사항을 유저에게 보여줍니다.
  4. 명령 실행 : 말그대로 명령. 이벤트가 발생하면 해당 이벤트에 맞게 명령합니다.

<img src="C:\Users\power\Downloads\Untitled (4).png" style="zoom:50%;" />

여기 그림에서 Model, Controller, View가 MVC에 해당됩니다. 그런데 저희가 배운 Spring MVC는 무엇일까요?

2) Spring MVC

간략한 역사는 2003년 Rod Johnson에 의해 처음 공개 되었는데 J2EE(현재 Java EE or Jakarta EE) 개발에 불편함과 복잡성을 줄이기 위해 개발했습니다. 왜 복잡하다고 할까요?

Spring Framework는 대규모 엔터프라이즈 애플리케이션을 개발하는 광범위 플랫폼입니다. 하지만 개발이 복잡한데 이유는

  1. 다양한 기술과 스펙 : 사용법을 익히는데 복잡합니다.
  2. 환경 설정과 배포 : J2EE api는 서버가 따로 필요하며 이러한 서버의 설정과 배포는 복잡성을 더합니다.
  3. 무거운 EJB 컴포넌트 : EJB는 분산 컴포넌트 모델을 제공했음에도 무거워 개발, 테스트, 디버깅이 힘들었습니다. (EJB는 Enterprise JavaBeans으로 쉽게 말하면 비지니스 로직을 캡슐화하고 보안, 리모트 엑세스, 생명 주기를 관리합니다.)
  4. XML설정 : 환경설정만 수백줄.. 말 다함.

등이 있습니다. 자세히는 기술 안하지만 옆에 멘트 달아 놓았습니다.

그럼 spring MVC에 대해 알아보겠습니다.

(1) **DispatcherServlet**

spring 공식 문서에 Spring MVC에 대한 설명에서

‘DispatcherServlet이 중앙에서 HTTP 요청을 처리해주는데 이는 Front Controller 패턴으로 설계되어있다’

이 얘기가 나옵니다. 그렇다면 `Servlet`부터 알아보도록 하죠

① Servlet

Servlet은 Java EE의 일부로 서버에서 작동하는 클래스입니다. **HTTP 프로토콜을 사용해 클라이언트에 요청을 처리하는 웹 api 개발**에 사용됩니다. `Servlet``HTML`, `XML`, `JSON` 등의 형태로 데이터를 클라이언트에 전달할 수 있습니다.

공부하다가 Servlet Life Cycle이 있어 소개합니다.

**초기화(Initialization)**->**서비스(Service)**->**소멸(Destruction)**

![](C:\Users\power\Downloads\다운로드.png)

코드로 진행이 되면

  1. 요청이 오면 Servlet의 인스턴스인 init() 메서드에 의해 Servlet을 초기화 합니다.
  2. service() 메서드를 호출하여 HTTP 요청 방식(GET, POST, PUT, DELETE etc)에 따라 적절하게 `doget()`, `doPost()`, `doPut`, `doDelete`등의 메서드로 처리합니다.
  3. 소멸과정은 Servlet이 필요하지 않다면 `destroy()`메서드를 호출하여 종료 작업을 수행합니다.

② Front Controller

![](C:\Users\power\Downloads\Untitled (5).png)

HTTP 요청이 오면 Servlet이 요청을 분석하고 `Handler mapping`을 통해 `Controller`를 찾아 요청을 전달합니다.

@RestController		//controller 에너테이션
public class HelloController {
    @GetMapping("/api/hello")		//HelloController의 hello() 함수 
    public String hello() {
        return "Hello World!";
    }
}

`Controller`는 요청에 대한 처리를 완료 후 처리에 대한 결과를 `Model``View` 정보를 전달합니다.

2. DTO CREATE READ

Data Transfer Object의 약자입니다. 복잡한 시스템 간 데이터 전송을 단순화하는데 사용되는 패턴이고 DTO는 일반적으로 분산 애플리케이션, RESTful 서비스, SOAP 서비스에서 사용됩니다.

여기서 RESTful은 현재 스프링으로 다루고 있는데 Representational State Transfer (REST) 아키텍처 스타일을 따르는 웹 서비스를 말합니다.

여기서

**Representational State Transfer (REST) 아키텍처 스타일**이란?

REST는 HTTP에 대한 이해에서 기반하며 서버와 클라이언트의 통신을 단순화하고 표준화하는데 있습니다.

핵심 몇 가지로 알아보면

  1. 클라이언트-서버 아키텍쳐 : 서버와 클라이언트가 독립적인 역할을 가지게 하여 서로 진화할 수 있게합니다.
  2. 무상태 : 각 요청이 자체적으로 이해해야 하니까 이해에 필요한 모든 정보가 있어야합니다.
  3. 캐싱 : 클라이언트의 서버 응답을 캐시할 수 있어야 합니다.
  4. 레이어드 시스템 : 클라이언트가 보낸 요청을 최종 서버에서 알 필요가 없으므로 유연성과 보안을 높힙니다.
  5. CRUD : creat, read, update, delete로 구성되며 통신을 단순화하는데 목적이 있습니다.

**웹 캐시**: 웹 캐시는 웹 브라우저나 서버에서 사용됩니다. 웹 페이지나 이미지 등의 컨텐츠를 임시로 저장하여, 같은 요청이 다시 오면 원격 서버에 접근하는 대신 캐시된 데이터를 제공함으로써 응답 시간을 줄입니다.

그래서 DTO 패턴이 뭐냐

DTO패턴에는 create와 read로 나누어집니다.

DTO를 사용하여 데이터를 생성하고, 이를 서버에 전송합니다. 서버는 DTO를 사용하여 데이터베이스에 저장합니다.

DTO를 사용하여 데이터를 읽고 섭에는 데이터 베이스에서 정보를 읽어 DTO로 변환하여 이를 클라이언트에 전달합니다. 그리고 클라이언트도 DTO를 사용하여 읽습니다.

![](C:\Users\power\Downloads\2021-04-25-layered-architecture.png)

이그림을 보면 DTO 객체를 사용하여 계층간의 데이터를 이동합니다.

그런데 이것을 보다보면 한가지 생각이 드는게 **아 계층간의 직접적인 데이터 전송을 금하는구나**를 알 수 있습니다.

Dao,vo

request dto를 받을

Jackson때문에 response에서 역직렬화를 할 때 변환을 못해주므로 생성자 필수입니다.

3. IoC Container & Bean

1) IoC Container

IoC가 나름의 해석을 한다면... 아이언맨이 슈트 보고 난 레이저나 쏠테니 넌 움직이렴~ 이런느낌입니다.

생명주기와 의존성을 관리한다...어렵습니다.

  1. **의존성 주입(Dependency Injection)**: IoC 컨테이너는 의존성 주입을 통해 객체간의 의존성을 관리합니다. 이를 통해 테스트 용이성이 향상되고, 코드의 모듈성과 유연성이 향상됩니다.
  2. **객체 생명주기 관리**: IoC 컨테이너는 객체의 생명주기를 관리합니다. 이를 통해 개발자는 객체의 생성, 사용, 소멸과 같은 절차를 직접 관리할 필요가 없습니다.
  3. **설정 및 부트스트래핑**: IoC 컨테이너는 애플리케이션의 초기 설정 및 부트스트래핑을 담당합니다.

2) 의존성 주입

**apllication context**

싱글톤

말그대로 의존한다는 것인데 여기서 강한 결합과 약한 결합이 있습니다.

(1) 강한 결합

**객체 A****객체 B**에 대해 많은 정보를 알고 있거나, **객체 A****객체 B**의 변경에 대해 직접적으로 영향을 받는 경우

public class OrderService {
    private OrderRepository orderRepository = new OrderRepository();	//여기 강하게 결합
    //왜냐면 구체적인 인스턴스를 직접 만들고 있음.
    public void createOrder(Order order) {
        orderRepository.save(order);
    }
}

(2) 약한 결합

**객체 A****객체 B**에 대해 적은 정보만 알고 있고, **객체 B**의 구체적인 내용에 대해서는 알지 못하거나 신경 쓰지 않는 경우

public class OrderService {
    private OrderRepository orderRepository; //인스턴스 직접 생성x-> 주입 받고 있음
    // 그래서 OrderRepository이 변경 되어도 OrderService는 따로임
    public OrderService(OrderRepository orderRepository) {
        this.orderRepository = orderRepository;
    }
    
    public void createOrder(Order order) {
        orderRepository.save(order);
    }
}

이렇게 약한 결합으로 해놓으면 **변경하거나 확장이 쉬워집니다.** MVC패턴에 적합한 설계 방식이라고 볼 수 있습니다.

이 또한 세가지로 나누는데

**필드 주입, 메서드 주입, 생성자 주입**

① 필드 주입

@Service
public class OrderService {
    @Autowired	//필드에 주입
    private OrderRepository orderRepository;

    public void createOrder(Order order) {
        orderRepository.save(order);
    }
}

② 생성자 주

1. Spring MVC란 무엇인가?

Spring MVC를 알기 전에 MVC 패턴를 알아야 합니다.

1) MVC패턴

Model-View-Controller의 줄임말로 어플리케이션을 구조화하는 방법입니다.

여기서 어플리케이션을 구조화하는 이유는 개발 과정에서 찾아볼 수 있는데 정리한다면

  1. **가독성** : 이해와 수정이 쉬움
  2. **재사용성** : 모듈화로 동일한 코드 사용 가능
  3. **유지보수** : 문제 발생시 보수하기 쉬움
  4. **확장성** : 기존 기능을 확장하기 쉬움
  5. **테스트 용이성** : 모듈화가 잘 되어 있으면 독립적인 테스트가 용이합니다.

그래서 구조화하는 방법 중 한가지인 MVC는 세가지로 분리하여 설계되어 있는데 **모델, 뷰, 컨트롤러**로 나누게 됩니다.

(1) 모델 (Model)

모델은 어플리케이션의 **정보나 데이터**를 표현합니다. 여기서 모델을 자세히 보게 되면 몇가지 역할로 나눌 수 있습니다.

  1. 데이터 엑세스 : 모델은 말그대로 데이터에 **추가** ,**접근**하고 **조작**하는 로직을 포함합니다.
  2. 비즈니스 로직 : 말이 요상시리 한데 **핵심 기능**을 말합니다. 쇼핑몰로 따지면 재고 관리, 계산, 주문 처리, 배송 처리 등이 있습니다.
  3. 데이터 유효성 : 데이터가 제대로 왔는지 보는 작업입니다. **데이터의 형식과 값**을 비교한다고 생각하시면 됩니다.
  4. 상태 관리 : 어플리케이션을 추적 관리하는 역할입니다. 예를 들면 로그인 상태, 진행중인 상태, 종료 상태 등을 말합니다.

(2) 뷰(View)

포장지라고 생각하면 편합니다. 시각적으로 표현해주고 모델의 데이터를 유저가 이해하기 쉬운 형태로 변환합니다.

뷰의 역할을 몇가지 나누었습니다.

  1. 데이터 표시 : 데이터를 사용자에게 표시하는 기능을 담당
  2. 사용자 인터랙션 : 버튼, 텍스트 입력 등 어플리케이션과의 상호 작용을 담당합니다.
  3. 사용자 피드백 : 유는 결국 뷰를 보고 사용하기 때문에 실제 상용화했을 때 피드백을 유저에게 얻습니다.

(3) 컨트롤러(Controller)

유저의 입력을 모델로 반영한다 생각하면 됩니다. 위에서 뷰가 상호작용 버튼을 누르면 컨트롤러가 적당한 모델을 찾아 실행합니다.

  1. 사용자 입력 처리 : 유저의 입력을 처리합니다. 뷰에서의 버튼이나 텍스트가 입력을 받아 작업을 수행합니다.
  2. 모델 변경 : 유저가 특정 데이터 수정을 하면 그에 맞게 모델의 상태를 변경합니다.
  3. 뷰 업데이트 : 모델입 변경되면 그에 맞는 변경사항을 유저에게 보여줍니다.
  4. 명령 실행 : 말그대로 명령. 이벤트가 발생하면 해당 이벤트에 맞게 명령합니다.

<img src="C:\Users\power\Downloads\Untitled (4).png" style="zoom:50%;" />

여기 그림에서 Model, Controller, View가 MVC에 해당됩니다. 그런데 저희가 배운 Spring MVC는 무엇일까요?

2) Spring MVC

간략한 역사는 2003년 Rod Johnson에 의해 처음 공개 되었는데 J2EE(현재 Java EE or Jakarta EE) 개발에 불편함과 복잡성을 줄이기 위해 개발했습니다. 왜 복잡하다고 할까요?

Spring Framework는 대규모 엔터프라이즈 애플리케이션을 개발하는 광범위 플랫폼입니다. 하지만 개발이 복잡한데 이유는

  1. 다양한 기술과 스펙 : 사용법을 익히는데 복잡합니다.
  2. 환경 설정과 배포 : J2EE api는 서버가 따로 필요하며 이러한 서버의 설정과 배포는 복잡성을 더합니다.
  3. 무거운 EJB 컴포넌트 : EJB는 분산 컴포넌트 모델을 제공했음에도 무거워 개발, 테스트, 디버깅이 힘들었습니다. (EJB는 Enterprise JavaBeans으로 쉽게 말하면 비지니스 로직을 캡슐화하고 보안, 리모트 엑세스, 생명 주기를 관리합니다.)
  4. XML설정 : 환경설정만 수백줄.. 말 다함.

등이 있습니다. 자세히는 기술 안하지만 옆에 멘트 달아 놓았습니다.

그럼 spring MVC에 대해 알아보겠습니다.

(1) **DispatcherServlet**

spring 공식 문서에 Spring MVC에 대한 설명에서

‘DispatcherServlet이 중앙에서 HTTP 요청을 처리해주는데 이는 Front Controller 패턴으로 설계되어있다’

이 얘기가 나옵니다. 그렇다면 `Servlet`부터 알아보도록 하죠

① Servlet

Servlet은 Java EE의 일부로 서버에서 작동하는 클래스입니다. **HTTP 프로토콜을 사용해 클라이언트에 요청을 처리하는 웹 api 개발**에 사용됩니다. `Servlet``HTML`, `XML`, `JSON` 등의 형태로 데이터를 클라이언트에 전달할 수 있습니다.

공부하다가 Servlet Life Cycle이 있어 소개합니다.

**초기화(Initialization)**->**서비스(Service)**->**소멸(Destruction)**

![](C:\Users\power\Downloads\다운로드.png)

코드로 진행이 되면

  1. 요청이 오면 Servlet의 인스턴스인 init() 메서드에 의해 Servlet을 초기화 합니다.
  2. service() 메서드를 호출하여 HTTP 요청 방식(GET, POST, PUT, DELETE etc)에 따라 적절하게 `doget()`, `doPost()`, `doPut`, `doDelete`등의 메서드로 처리합니다.
  3. 소멸과정은 Servlet이 필요하지 않다면 `destroy()`메서드를 호출하여 종료 작업을 수행합니다.

② Front Controller

![](C:\Users\power\Downloads\Untitled (5).png)

HTTP 요청이 오면 Servlet이 요청을 분석하고 `Handler mapping`을 통해 `Controller`를 찾아 요청을 전달합니다.

@RestController		//controller 에너테이션
public class HelloController {
    @GetMapping("/api/hello")		//HelloController의 hello() 함수 
    public String hello() {
        return "Hello World!";
    }
}

`Controller`는 요청에 대한 처리를 완료 후 처리에 대한 결과를 `Model``View` 정보를 전달합니다.

2. DTO CREATE READ

Data Transfer Object의 약자입니다. 복잡한 시스템 간 데이터 전송을 단순화하는데 사용되는 패턴이고 DTO는 일반적으로 분산 애플리케이션, RESTful 서비스, SOAP 서비스에서 사용됩니다.

여기서 RESTful은 현재 스프링으로 다루고 있는데 Representational State Transfer (REST) 아키텍처 스타일을 따르는 웹 서비스를 말합니다.

여기서

**Representational State Transfer (REST) 아키텍처 스타일**이란?

REST는 HTTP에 대한 이해에서 기반하며 서버와 클라이언트의 통신을 단순화하고 표준화하는데 있습니다.

핵심 몇 가지로 알아보면

  1. 클라이언트-서버 아키텍쳐 : 서버와 클라이언트가 독립적인 역할을 가지게 하여 서로 진화할 수 있게합니다.
  2. 무상태 : 각 요청이 자체적으로 이해해야 하니까 이해에 필요한 모든 정보가 있어야합니다.
  3. 캐싱 : 클라이언트의 서버 응답을 캐시할 수 있어야 합니다.
  4. 레이어드 시스템 : 클라이언트가 보낸 요청을 최종 서버에서 알 필요가 없으므로 유연성과 보안을 높힙니다.
  5. CRUD : creat, read, update, delete로 구성되며 통신을 단순화하는데 목적이 있습니다.

**웹 캐시**: 웹 캐시는 웹 브라우저나 서버에서 사용됩니다. 웹 페이지나 이미지 등의 컨텐츠를 임시로 저장하여, 같은 요청이 다시 오면 원격 서버에 접근하는 대신 캐시된 데이터를 제공함으로써 응답 시간을 줄입니다.

그래서 DTO 패턴이 뭐냐

DTO패턴에는 create와 read로 나누어집니다.

DTO를 사용하여 데이터를 생성하고, 이를 서버에 전송합니다. 서버는 DTO를 사용하여 데이터베이스에 저장합니다.

DTO를 사용하여 데이터를 읽고 섭에는 데이터 베이스에서 정보를 읽어 DTO로 변환하여 이를 클라이언트에 전달합니다. 그리고 클라이언트도 DTO를 사용하여 읽습니다.

![](C:\Users\power\Downloads\2021-04-25-layered-architecture.png)

이그림을 보면 DTO 객체를 사용하여 계층간의 데이터를 이동합니다.

그런데 이것을 보다보면 한가지 생각이 드는게 **아 계층간의 직접적인 데이터 전송을 금하는구나**를 알 수 있습니다.

Dao,vo

request dto를 받을

Jackson때문에 response에서 역직렬화를 할 때 변환을 못해주므로 생성자 필수입니다.

3. IoC Container & Bean

1) IoC Container

IoC가 나름의 해석을 한다면... 아이언맨이 슈트 보고 난 레이저나 쏠테니 넌 움직이렴~ 이런느낌입니다.

생명주기와 의존성을 관리한다...어렵습니다.

  1. **의존성 주입(Dependency Injection)**: IoC 컨테이너는 의존성 주입을 통해 객체간의 의존성을 관리합니다. 이를 통해 테스트 용이성이 향상되고, 코드의 모듈성과 유연성이 향상됩니다.
  2. **객체 생명주기 관리**: IoC 컨테이너는 객체의 생명주기를 관리합니다. 이를 통해 개발자는 객체의 생성, 사용, 소멸과 같은 절차를 직접 관리할 필요가 없습니다.
  3. **설정 및 부트스트래핑**: IoC 컨테이너는 애플리케이션의 초기 설정 및 부트스트래핑을 담당합니다.

2) 의존성 주입

**apllication context**

싱글톤

말그대로 의존한다는 것인데 여기서 강한 결합과 약한 결합이 있습니다.

(1) 강한 결합

**객체 A****객체 B**에 대해 많은 정보를 알고 있거나, **객체 A****객체 B**의 변경에 대해 직접적으로 영향을 받는 경우

public class OrderService {
    private OrderRepository orderRepository = new OrderRepository();	//여기 강하게 결합
    //왜냐면 구체적인 인스턴스를 직접 만들고 있음.
    public void createOrder(Order order) {
        orderRepository.save(order);
    }
}

(2) 약한 결합

**객체 A****객체 B**에 대해 적은 정보만 알고 있고, **객체 B**의 구체적인 내용에 대해서는 알지 못하거나 신경 쓰지 않는 경우

public class OrderService {
    private OrderRepository orderRepository; //인스턴스 직접 생성x-> 주입 받고 있음
    // 그래서 OrderRepository이 변경 되어도 OrderService는 따로임
    public OrderService(OrderRepository orderRepository) {
        this.orderRepository = orderRepository;
    }
    
    public void createOrder(Order order) {
        orderRepository.save(order);
    }
}

이렇게 약한 결합으로 해놓으면 **변경하거나 확장이 쉬워집니다.** MVC패턴에 적합한 설계 방식이라고 볼 수 있습니다.

이 또한 세가지로 나누는데

**필드 주입, 메서드 주입, 생성자 주입**

① 필드 주입

@Service
public class OrderService {
    @Autowired	//필드에 주입
    private OrderRepository orderRepository;

    public void createOrder(Order order) {
        orderRepository.save(order);
    }
}

② 생성자 주

1. Spring MVC란 무엇인가?

Spring MVC를 알기 전에 MVC 패턴를 알아야 합니다.

1) MVC패턴

Model-View-Controller의 줄임말로 어플리케이션을 구조화하는 방법입니다.

여기서 어플리케이션을 구조화하는 이유는 개발 과정에서 찾아볼 수 있는데 정리한다면

  1. **가독성** : 이해와 수정이 쉬움
  2. **재사용성** : 모듈화로 동일한 코드 사용 가능
  3. **유지보수** : 문제 발생시 보수하기 쉬움
  4. **확장성** : 기존 기능을 확장하기 쉬움
  5. **테스트 용이성** : 모듈화가 잘 되어 있으면 독립적인 테스트가 용이합니다.

그래서 구조화하는 방법 중 한가지인 MVC는 세가지로 분리하여 설계되어 있는데 **모델, 뷰, 컨트롤러**로 나누게 됩니다.

(1) 모델 (Model)

모델은 어플리케이션의 **정보나 데이터**를 표현합니다. 여기서 모델을 자세히 보게 되면 몇가지 역할로 나눌 수 있습니다.

  1. 데이터 엑세스 : 모델은 말그대로 데이터에 **추가** ,**접근**하고 **조작**하는 로직을 포함합니다.
  2. 비즈니스 로직 : 말이 요상시리 한데 **핵심 기능**을 말합니다. 쇼핑몰로 따지면 재고 관리, 계산, 주문 처리, 배송 처리 등이 있습니다.
  3. 데이터 유효성 : 데이터가 제대로 왔는지 보는 작업입니다. **데이터의 형식과 값**을 비교한다고 생각하시면 됩니다.
  4. 상태 관리 : 어플리케이션을 추적 관리하는 역할입니다. 예를 들면 로그인 상태, 진행중인 상태, 종료 상태 등을 말합니다.

(2) 뷰(View)

포장지라고 생각하면 편합니다. 시각적으로 표현해주고 모델의 데이터를 유저가 이해하기 쉬운 형태로 변환합니다.

뷰의 역할을 몇가지 나누었습니다.

  1. 데이터 표시 : 데이터를 사용자에게 표시하는 기능을 담당
  2. 사용자 인터랙션 : 버튼, 텍스트 입력 등 어플리케이션과의 상호 작용을 담당합니다.
  3. 사용자 피드백 : 유는 결국 뷰를 보고 사용하기 때문에 실제 상용화했을 때 피드백을 유저에게 얻습니다.

(3) 컨트롤러(Controller)

유저의 입력을 모델로 반영한다 생각하면 됩니다. 위에서 뷰가 상호작용 버튼을 누르면 컨트롤러가 적당한 모델을 찾아 실행합니다.

  1. 사용자 입력 처리 : 유저의 입력을 처리합니다. 뷰에서의 버튼이나 텍스트가 입력을 받아 작업을 수행합니다.
  2. 모델 변경 : 유저가 특정 데이터 수정을 하면 그에 맞게 모델의 상태를 변경합니다.
  3. 뷰 업데이트 : 모델입 변경되면 그에 맞는 변경사항을 유저에게 보여줍니다.
  4. 명령 실행 : 말그대로 명령. 이벤트가 발생하면 해당 이벤트에 맞게 명령합니다.

<img src="C:\Users\power\Downloads\Untitled (4).png" style="zoom:50%;" />

여기 그림에서 Model, Controller, View가 MVC에 해당됩니다. 그런데 저희가 배운 Spring MVC는 무엇일까요?

2) Spring MVC

간략한 역사는 2003년 Rod Johnson에 의해 처음 공개 되었는데 J2EE(현재 Java EE or Jakarta EE) 개발에 불편함과 복잡성을 줄이기 위해 개발했습니다. 왜 복잡하다고 할까요?

Spring Framework는 대규모 엔터프라이즈 애플리케이션을 개발하는 광범위 플랫폼입니다. 하지만 개발이 복잡한데 이유는

  1. 다양한 기술과 스펙 : 사용법을 익히는데 복잡합니다.
  2. 환경 설정과 배포 : J2EE api는 서버가 따로 필요하며 이러한 서버의 설정과 배포는 복잡성을 더합니다.
  3. 무거운 EJB 컴포넌트 : EJB는 분산 컴포넌트 모델을 제공했음에도 무거워 개발, 테스트, 디버깅이 힘들었습니다. (EJB는 Enterprise JavaBeans으로 쉽게 말하면 비지니스 로직을 캡슐화하고 보안, 리모트 엑세스, 생명 주기를 관리합니다.)
  4. XML설정 : 환경설정만 수백줄.. 말 다함.

등이 있습니다. 자세히는 기술 안하지만 옆에 멘트 달아 놓았습니다.

그럼 spring MVC에 대해 알아보겠습니다.

(1) **DispatcherServlet**

spring 공식 문서에 Spring MVC에 대한 설명에서

‘DispatcherServlet이 중앙에서 HTTP 요청을 처리해주는데 이는 Front Controller 패턴으로 설계되어있다’

이 얘기가 나옵니다. 그렇다면 `Servlet`부터 알아보도록 하죠

① Servlet

Servlet은 Java EE의 일부로 서버에서 작동하는 클래스입니다. **HTTP 프로토콜을 사용해 클라이언트에 요청을 처리하는 웹 api 개발**에 사용됩니다. `Servlet``HTML`, `XML`, `JSON` 등의 형태로 데이터를 클라이언트에 전달할 수 있습니다.

공부하다가 Servlet Life Cycle이 있어 소개합니다.

**초기화(Initialization)**->**서비스(Service)**->**소멸(Destruction)**

![](C:\Users\power\Downloads\다운로드.png)

코드로 진행이 되면

  1. 요청이 오면 Servlet의 인스턴스인 init() 메서드에 의해 Servlet을 초기화 합니다.
  2. service() 메서드를 호출하여 HTTP 요청 방식(GET, POST, PUT, DELETE etc)에 따라 적절하게 `doget()`, `doPost()`, `doPut`, `doDelete`등의 메서드로 처리합니다.
  3. 소멸과정은 Servlet이 필요하지 않다면 `destroy()`메서드를 호출하여 종료 작업을 수행합니다.

② Front Controller

![](C:\Users\power\Downloads\Untitled (5).png)

HTTP 요청이 오면 Servlet이 요청을 분석하고 `Handler mapping`을 통해 `Controller`를 찾아 요청을 전달합니다.

@RestController		//controller 에너테이션
public class HelloController {
    @GetMapping("/api/hello")		//HelloController의 hello() 함수 
    public String hello() {
        return "Hello World!";
    }
}

`Controller`는 요청에 대한 처리를 완료 후 처리에 대한 결과를 `Model``View` 정보를 전달합니다.

2. DTO CREATE READ

Data Transfer Object의 약자입니다. 복잡한 시스템 간 데이터 전송을 단순화하는데 사용되는 패턴이고 DTO는 일반적으로 분산 애플리케이션, RESTful 서비스, SOAP 서비스에서 사용됩니다.

여기서 RESTful은 현재 스프링으로 다루고 있는데 Representational State Transfer (REST) 아키텍처 스타일을 따르는 웹 서비스를 말합니다.

여기서

**Representational State Transfer (REST) 아키텍처 스타일**이란?

REST는 HTTP에 대한 이해에서 기반하며 서버와 클라이언트의 통신을 단순화하고 표준화하는데 있습니다.

핵심 몇 가지로 알아보면

  1. 클라이언트-서버 아키텍쳐 : 서버와 클라이언트가 독립적인 역할을 가지게 하여 서로 진화할 수 있게합니다.
  2. 무상태 : 각 요청이 자체적으로 이해해야 하니까 이해에 필요한 모든 정보가 있어야합니다.
  3. 캐싱 : 클라이언트의 서버 응답을 캐시할 수 있어야 합니다.
  4. 레이어드 시스템 : 클라이언트가 보낸 요청을 최종 서버에서 알 필요가 없으므로 유연성과 보안을 높힙니다.
  5. CRUD : creat, read, update, delete로 구성되며 통신을 단순화하는데 목적이 있습니다.

**웹 캐시**: 웹 캐시는 웹 브라우저나 서버에서 사용됩니다. 웹 페이지나 이미지 등의 컨텐츠를 임시로 저장하여, 같은 요청이 다시 오면 원격 서버에 접근하는 대신 캐시된 데이터를 제공함으로써 응답 시간을 줄입니다.

그래서 DTO 패턴이 뭐냐

DTO패턴에는 create와 read로 나누어집니다.

DTO를 사용하여 데이터를 생성하고, 이를 서버에 전송합니다. 서버는 DTO를 사용하여 데이터베이스에 저장합니다.

DTO를 사용하여 데이터를 읽고 섭에는 데이터 베이스에서 정보를 읽어 DTO로 변환하여 이를 클라이언트에 전달합니다. 그리고 클라이언트도 DTO를 사용하여 읽습니다.

![](C:\Users\power\Downloads\2021-04-25-layered-architecture.png)

이그림을 보면 DTO 객체를 사용하여 계층간의 데이터를 이동합니다.

그런데 이것을 보다보면 한가지 생각이 드는게 **아 계층간의 직접적인 데이터 전송을 금하는구나**를 알 수 있습니다.

Dao,vo

request dto를 받을

Jackson때문에 response에서 역직렬화를 할 때 변환을 못해주므로 생성자 필수입니다.

3. IoC Container & Bean

1) IoC Container

IoC가 나름의 해석을 한다면... 아이언맨이 슈트 보고 난 레이저나 쏠테니 넌 움직이렴~ 이런느낌입니다.

생명주기와 의존성을 관리한다...어렵습니다.

  1. **의존성 주입(Dependency Injection)**: IoC 컨테이너는 의존성 주입을 통해 객체간의 의존성을 관리합니다. 이를 통해 테스트 용이성이 향상되고, 코드의 모듈성과 유연성이 향상됩니다.
  2. **객체 생명주기 관리**: IoC 컨테이너는 객체의 생명주기를 관리합니다. 이를 통해 개발자는 객체의 생성, 사용, 소멸과 같은 절차를 직접 관리할 필요가 없습니다.
  3. **설정 및 부트스트래핑**: IoC 컨테이너는 애플리케이션의 초기 설정 및 부트스트래핑을 담당합니다.

2) 의존성 주입

**apllication context**

싱글톤

말그대로 의존한다는 것인데 여기서 강한 결합과 약한 결합이 있습니다.

(1) 강한 결합

**객체 A****객체 B**에 대해 많은 정보를 알고 있거나, **객체 A****객체 B**의 변경에 대해 직접적으로 영향을 받는 경우

public class OrderService {
    private OrderRepository orderRepository = new OrderRepository();	//여기 강하게 결합
    //왜냐면 구체적인 인스턴스를 직접 만들고 있음.
    public void createOrder(Order order) {
        orderRepository.save(order);
    }
}

(2) 약한 결합

**객체 A****객체 B**에 대해 적은 정보만 알고 있고, **객체 B**의 구체적인 내용에 대해서는 알지 못하거나 신경 쓰지 않는 경우

public class OrderService {
    private OrderRepository orderRepository; //인스턴스 직접 생성x-> 주입 받고 있음
    // 그래서 OrderRepository이 변경 되어도 OrderService는 따로임
    public OrderService(OrderRepository orderRepository) {
        this.orderRepository = orderRepository;
    }
    
    public void createOrder(Order order) {
        orderRepository.save(order);
    }
}

이렇게 약한 결합으로 해놓으면 **변경하거나 확장이 쉬워집니다.** MVC패턴에 적합한 설계 방식이라고 볼 수 있습니다.

이 또한 세가지로 나누는데

**필드 주입, 메서드 주입, 생성자 주입**

① 필드 주입

@Service
public class OrderService {
    @Autowired	//필드에 주입
    private OrderRepository orderRepository;

    public void createOrder(Order order) {
        orderRepository.save(order);
    }
}

② 생성자 주

1. Spring MVC란 무엇인가?

Spring MVC를 알기 전에 MVC 패턴를 알아야 합니다.

1) MVC패턴

Model-View-Controller의 줄임말로 어플리케이션을 구조화하는 방법입니다.

여기서 어플리케이션을 구조화하는 이유는 개발 과정에서 찾아볼 수 있는데 정리한다면

  1. **가독성** : 이해와 수정이 쉬움
  2. **재사용성** : 모듈화로 동일한 코드 사용 가능
  3. **유지보수** : 문제 발생시 보수하기 쉬움
  4. **확장성** : 기존 기능을 확장하기 쉬움
  5. **테스트 용이성** : 모듈화가 잘 되어 있으면 독립적인 테스트가 용이합니다.

그래서 구조화하는 방법 중 한가지인 MVC는 세가지로 분리하여 설계되어 있는데 **모델, 뷰, 컨트롤러**로 나누게 됩니다.

(1) 모델 (Model)

모델은 어플리케이션의 **정보나 데이터**를 표현합니다. 여기서 모델을 자세히 보게 되면 몇가지 역할로 나눌 수 있습니다.

  1. 데이터 엑세스 : 모델은 말그대로 데이터에 **추가** ,**접근**하고 **조작**하는 로직을 포함합니다.
  2. 비즈니스 로직 : 말이 요상시리 한데 **핵심 기능**을 말합니다. 쇼핑몰로 따지면 재고 관리, 계산, 주문 처리, 배송 처리 등이 있습니다.
  3. 데이터 유효성 : 데이터가 제대로 왔는지 보는 작업입니다. **데이터의 형식과 값**을 비교한다고 생각하시면 됩니다.
  4. 상태 관리 : 어플리케이션을 추적 관리하는 역할입니다. 예를 들면 로그인 상태, 진행중인 상태, 종료 상태 등을 말합니다.

(2) 뷰(View)

포장지라고 생각하면 편합니다. 시각적으로 표현해주고 모델의 데이터를 유저가 이해하기 쉬운 형태로 변환합니다.

뷰의 역할을 몇가지 나누었습니다.

  1. 데이터 표시 : 데이터를 사용자에게 표시하는 기능을 담당
  2. 사용자 인터랙션 : 버튼, 텍스트 입력 등 어플리케이션과의 상호 작용을 담당합니다.
  3. 사용자 피드백 : 유는 결국 뷰를 보고 사용하기 때문에 실제 상용화했을 때 피드백을 유저에게 얻습니다.

(3) 컨트롤러(Controller)

유저의 입력을 모델로 반영한다 생각하면 됩니다. 위에서 뷰가 상호작용 버튼을 누르면 컨트롤러가 적당한 모델을 찾아 실행합니다.

  1. 사용자 입력 처리 : 유저의 입력을 처리합니다. 뷰에서의 버튼이나 텍스트가 입력을 받아 작업을 수행합니다.
  2. 모델 변경 : 유저가 특정 데이터 수정을 하면 그에 맞게 모델의 상태를 변경합니다.
  3. 뷰 업데이트 : 모델입 변경되면 그에 맞는 변경사항을 유저에게 보여줍니다.
  4. 명령 실행 : 말그대로 명령. 이벤트가 발생하면 해당 이벤트에 맞게 명령합니다.

<img src="C:\Users\power\Downloads\Untitled (4).png" style="zoom:50%;" />

여기 그림에서 Model, Controller, View가 MVC에 해당됩니다. 그런데 저희가 배운 Spring MVC는 무엇일까요?

2) Spring MVC

간략한 역사는 2003년 Rod Johnson에 의해 처음 공개 되었는데 J2EE(현재 Java EE or Jakarta EE) 개발에 불편함과 복잡성을 줄이기 위해 개발했습니다. 왜 복잡하다고 할까요?

Spring Framework는 대규모 엔터프라이즈 애플리케이션을 개발하는 광범위 플랫폼입니다. 하지만 개발이 복잡한데 이유는

  1. 다양한 기술과 스펙 : 사용법을 익히는데 복잡합니다.
  2. 환경 설정과 배포 : J2EE api는 서버가 따로 필요하며 이러한 서버의 설정과 배포는 복잡성을 더합니다.
  3. 무거운 EJB 컴포넌트 : EJB는 분산 컴포넌트 모델을 제공했음에도 무거워 개발, 테스트, 디버깅이 힘들었습니다. (EJB는 Enterprise JavaBeans으로 쉽게 말하면 비지니스 로직을 캡슐화하고 보안, 리모트 엑세스, 생명 주기를 관리합니다.)
  4. XML설정 : 환경설정만 수백줄.. 말 다함.

등이 있습니다. 자세히는 기술 안하지만 옆에 멘트 달아 놓았습니다.

그럼 spring MVC에 대해 알아보겠습니다.

(1) **DispatcherServlet**

spring 공식 문서에 Spring MVC에 대한 설명에서

‘DispatcherServlet이 중앙에서 HTTP 요청을 처리해주는데 이는 Front Controller 패턴으로 설계되어있다’

이 얘기가 나옵니다. 그렇다면 `Servlet`부터 알아보도록 하죠

① Servlet

Servlet은 Java EE의 일부로 서버에서 작동하는 클래스입니다. **HTTP 프로토콜을 사용해 클라이언트에 요청을 처리하는 웹 api 개발**에 사용됩니다. `Servlet``HTML`, `XML`, `JSON` 등의 형태로 데이터를 클라이언트에 전달할 수 있습니다.

공부하다가 Servlet Life Cycle이 있어 소개합니다.

**초기화(Initialization)**->**서비스(Service)**->**소멸(Destruction)**

![](C:\Users\power\Downloads\다운로드.png)

코드로 진행이 되면

  1. 요청이 오면 Servlet의 인스턴스인 init() 메서드에 의해 Servlet을 초기화 합니다.
  2. service() 메서드를 호출하여 HTTP 요청 방식(GET, POST, PUT, DELETE etc)에 따라 적절하게 `doget()`, `doPost()`, `doPut`, `doDelete`등의 메서드로 처리합니다.
  3. 소멸과정은 Servlet이 필요하지 않다면 `destroy()`메서드를 호출하여 종료 작업을 수행합니다.

② Front Controller

![](C:\Users\power\Downloads\Untitled (5).png)

HTTP 요청이 오면 Servlet이 요청을 분석하고 `Handler mapping`을 통해 `Controller`를 찾아 요청을 전달합니다.

@RestController		//controller 에너테이션
public class HelloController {
    @GetMapping("/api/hello")		//HelloController의 hello() 함수 
    public String hello() {
        return "Hello World!";
    }
}

`Controller`는 요청에 대한 처리를 완료 후 처리에 대한 결과를 `Model``View` 정보를 전달합니다.

2. DTO CREATE READ

Data Transfer Object의 약자입니다. 복잡한 시스템 간 데이터 전송을 단순화하는데 사용되는 패턴이고 DTO는 일반적으로 분산 애플리케이션, RESTful 서비스, SOAP 서비스에서 사용됩니다.

여기서 RESTful은 현재 스프링으로 다루고 있는데 Representational State Transfer (REST) 아키텍처 스타일을 따르는 웹 서비스를 말합니다.

여기서

**Representational State Transfer (REST) 아키텍처 스타일**이란?

REST는 HTTP에 대한 이해에서 기반하며 서버와 클라이언트의 통신을 단순화하고 표준화하는데 있습니다.

핵심 몇 가지로 알아보면

  1. 클라이언트-서버 아키텍쳐 : 서버와 클라이언트가 독립적인 역할을 가지게 하여 서로 진화할 수 있게합니다.
  2. 무상태 : 각 요청이 자체적으로 이해해야 하니까 이해에 필요한 모든 정보가 있어야합니다.
  3. 캐싱 : 클라이언트의 서버 응답을 캐시할 수 있어야 합니다.
  4. 레이어드 시스템 : 클라이언트가 보낸 요청을 최종 서버에서 알 필요가 없으므로 유연성과 보안을 높힙니다.
  5. CRUD : creat, read, update, delete로 구성되며 통신을 단순화하는데 목적이 있습니다.

**웹 캐시**: 웹 캐시는 웹 브라우저나 서버에서 사용됩니다. 웹 페이지나 이미지 등의 컨텐츠를 임시로 저장하여, 같은 요청이 다시 오면 원격 서버에 접근하는 대신 캐시된 데이터를 제공함으로써 응답 시간을 줄입니다.

그래서 DTO 패턴이 뭐냐

DTO패턴에는 create와 read로 나누어집니다.

DTO를 사용하여 데이터를 생성하고, 이를 서버에 전송합니다. 서버는 DTO를 사용하여 데이터베이스에 저장합니다.

DTO를 사용하여 데이터를 읽고 섭에는 데이터 베이스에서 정보를 읽어 DTO로 변환하여 이를 클라이언트에 전달합니다. 그리고 클라이언트도 DTO를 사용하여 읽습니다.

![](C:\Users\power\Downloads\2021-04-25-layered-architecture.png)

이그림을 보면 DTO 객체를 사용하여 계층간의 데이터를 이동합니다.

그런데 이것을 보다보면 한가지 생각이 드는게 **아 계층간의 직접적인 데이터 전송을 금하는구나**를 알 수 있습니다.

Dao,vo

request dto를 받을

Jackson때문에 response에서 역직렬화를 할 때 변환을 못해주므로 생성자 필수입니다.

3. IoC Container & Bean

1) IoC Container

IoC가 나름의 해석을 한다면... 아이언맨이 슈트 보고 난 레이저나 쏠테니 넌 움직이렴~ 이런느낌입니다.

생명주기와 의존성을 관리한다...어렵습니다.

  1. **의존성 주입(Dependency Injection)**: IoC 컨테이너는 의존성 주입을 통해 객체간의 의존성을 관리합니다. 이를 통해 테스트 용이성이 향상되고, 코드의 모듈성과 유연성이 향상됩니다.
  2. **객체 생명주기 관리**: IoC 컨테이너는 객체의 생명주기를 관리합니다. 이를 통해 개발자는 객체의 생성, 사용, 소멸과 같은 절차를 직접 관리할 필요가 없습니다.
  3. **설정 및 부트스트래핑**: IoC 컨테이너는 애플리케이션의 초기 설정 및 부트스트래핑을 담당합니다.

2) 의존성 주입

**apllication context**

싱글톤

말그대로 의존한다는 것인데 여기서 강한 결합과 약한 결합이 있습니다.

(1) 강한 결합

**객체 A****객체 B**에 대해 많은 정보를 알고 있거나, **객체 A****객체 B**의 변경에 대해 직접적으로 영향을 받는 경우

public class OrderService {
    private OrderRepository orderRepository = new OrderRepository();	//여기 강하게 결합
    //왜냐면 구체적인 인스턴스를 직접 만들고 있음.
    public void createOrder(Order order) {
        orderRepository.save(order);
    }
}

(2) 약한 결합

**객체 A****객체 B**에 대해 적은 정보만 알고 있고, **객체 B**의 구체적인 내용에 대해서는 알지 못하거나 신경 쓰지 않는 경우

public class OrderService {
    private OrderRepository orderRepository; //인스턴스 직접 생성x-> 주입 받고 있음
    // 그래서 OrderRepository이 변경 되어도 OrderService는 따로임
    public OrderService(OrderRepository orderRepository) {
        this.orderRepository = orderRepository;
    }
    
    public void createOrder(Order order) {
        orderRepository.save(order);
    }
}

이렇게 약한 결합으로 해놓으면 **변경하거나 확장이 쉬워집니다.** MVC패턴에 적합한 설계 방식이라고 볼 수 있습니다.

이 또한 세가지로 나누는데

**필드 주입, 메서드 주입, 생성자 주입**

① 필드 주입

@Service
public class OrderService {
    @Autowired	//필드에 주입
    private OrderRepository orderRepository;

    public void createOrder(Order order) {
        orderRepository.save(order);
    }
}

② 생성자 주

'항해99' 카테고리의 다른 글

[항해 99 TIL] 쿠키와 섹션  (0) 2023.06.30
[항해99 TIL] JPA  (0) 2023.06.30
[항해 99 WIL] 1주차 정리(Spring 시작)  (0) 2023.06.28
[항해 99 TIL] 예외 처리(exception handling)  (0) 2023.06.21
[항해 99 TIL] 스터디의 시작  (0) 2023.06.20