본문 바로가기
Be Smart/Spring

Spring MVC 프로젝트의 기본 구조와 실행 순서

by 반월하 2021. 10. 1.
728x90

1. Spring 개념

  - Spring은 개발 할 때 사용하는 Framework 입니다. 

한국어로 번역하면 Frame(틀) + work(일) 으로 일(개발)을 효율적으로 하기위해서 사용하는 틀(frame) 입니다. 

framework은 정해진 규칙을 지키면 개발의 생산성을 향상시킬 수 있는 특징이 있습니다.

일상생활에서 비유를 한다면 커피를 만들 때 핸드 드립으로 만드는것은 시간과 정성이 많이 소모되지만, 커피머신으로 커피를 만든다면 간단한 버튼조작만으로 빠르게 커피를 만들 수 있습니다.

(조작 : 원두 글라인딩/농도, 물 양/온도, 라떼 등)

여기서 커피를 만들기위해 커피머신이 하는 역할이 Spring Framework과 유사합니다.

프레임워크 중에서도 스프링 프레임워크는 자바 플랫폼을 위한 오픈소스 애플리케이션 프레임워크로서 엔터프라이즈급 애플리케이션을 개발하기 위한 모든 기능을 종합적으로 제공하는 경량화된 솔루션입니다.

엔터프라이즈급 개발이란 뜻대로만 풀이하면 기업을 대상으로 하는 개발이라는 말입니다. 즉, 대규모 데이터 처리와 트랜잭션이 동시에 여러 사용자로 부터 행해지는 매우 큰 규모의 환경을 엔터프라이즈 환경이라 일컫습니다.

Spirng Framework는 경량 컨테이너로 자바 객체를 담고 직접 관리합니다. 객체의 생성 및 소멸 그리고 라이프 사이클을관리하며 언제든 Spring 컨테이너로 부터 필요한 객체를 가져와 사용할 수 있습니다. 

 

Spring Framework의 특징 중에서도 

Spring Framework의 특징 MVC (Model2)

MVC란 (Model View Controller) 구조로 사용자 인터페이스와 비지니스 로직을 분리하여 개발 하는 것 입니다. MVC에서는 Model1과 Model2로 나누어져 있으며 일반적인 MVC는 Model2를 지칭합니다. 

 

Model

Model에서는 데이터처리를 담당하는 부분입니다. Model부분은 Serivce영역과 DAO영역으로 나누어지게 되고 여기서 중요한 것은 Service 부분은 불필요하게 HTTP통신을 하지 않아야하고 request나 response와 같은 객체를 매개변수로 받아선 안된다. 또한 Model 부분의 Service는 view에 종속적인 코드가 없어야 하고 View 부분이 변경되더라도 Service 부분은 그대로 재사용 할 수 있어야 한다.

Model에서는 View와 Controller 어떠한 정보도 가지고 있어서는 안된다.

 

View

View는 사용자 Interface를 담당하며 사용자에게 보여지는 부분입니다. View는 Controller를 통해 모델에 데이터에 대한 시각화를 담당하며 View는 자신이 요청을 보낼 Controller의 정보만 알고 있어야 하는 것이 핵심이다.

Model이 가지고 있는 정보를 저장해서는 안되며 Model, Controller에 구성 요소를 알아서는 안된다.

 

Controller

Controller에서는 View에 받은 요청을 가공하여 Model(Service 영역)에 이를 전달한다. 또한 Model로 부터 받은 결과를 View로 넘겨주는 역할을 합니다. Controller에서는 모든 요청 에러와 모델 에러를 처리하며 View와 Controller에 정보를 알고 있어야한다.

Model과 View의 정보에 대해 알고 있어야한다.

이렇게 Model, View, Controller를 나누는 이유는 소스를 분리함으로서 각 소스의 목적이 명확해 지고 유지보수하는데 있어서 용이하기 때문이다. Model의 Service영역은 자신을 어떠한 Controller가 호출하든 상관없이 정해진 매개변수만 받는다면 자신의 비즈니스 로직을 처리할 수 있어야한다. 

즉, 모듈화를 통해 어디서든 재사용이 가능하여야 한다는 뜻이다. 

이말은 View의 정보가 달라지더라도 Controller에서 Service에 넘겨줄 매개변수 데이터 가공만 처리하면 되기 때문에 유지보수 비용을 절감 할 수 있는 효과가 있다. 또한 Service영역의 재사용이 용이하기 때문에 확장성 부분에서도 큰 효과를 볼 수 있는 장점이있다.

Spring 파일의 기본 구성

 

Spring의 전체적인 실행 순서

Request -> DispatcherServlet -> HandlerMapping -> (Controller -> Service -> DAO -> DB -> DAO -> Service -> Controller) -> DispatcherServlet -> ViewResolver -> View -> DispatcherServlet -> Response

 

예시 1. 일반적인 기본 동작 순서

자세한 스프링 실행 순서

1. 클라이언트가 Request 요청을 하면, DispatcherServlet이 요청을 가로챈다. 이 때 DispatcherServlet이 모든 요청을 가로채는 건 아니고 web.xml에 등록된 내용만 가로챈다. 최초의 web.xml 에서는 <url-pattern>이 '/'와 같이 해당 애플리케이션의 모든 URL로 등록돼있기 때문에, 만약 *. do와 같이 특정 URL만 적용하고 싶다면 <url-pattern>의 내용을 바꿔주어 범위를 변경하면 된다.

2. DispatcherServlet이 가로챈 요청을 HandlerMapping에게 보내 해당 요청을 처리할 수 있는 Controller를 찾는다.

3. 실제 로직 처리 (Controller -> Service -> DAO -> DB -> DAO -> Service -> Controller)

4. 로직 처리 후 ViewResolver를 통해 view 화면을 찾는다.

5. 찾은 view 화면을 View에 보내면 이 결과를 다시 DispatcherServlet에 보내고, DispatcherServlet는 최종 클라이언트에게 전송한다.

 

자바 컨트롤러 파일(Java Controller File)

HomeController.java

package com.company.devpad;
import java.text.DateFormat; ...


@Controller
public class HomeController {


    private static final Logger logger = LoggerFactory.getLogger(HomeController.class);


    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String home(Locale locale, Model model) {
        logger.info("Welcome home! The client locale is {}.", locale);


        Date date = new Date();
        DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);


        String formattedDate = dateFormat.format(date);


        model.addAttribute("serverTime", formattedDate);


        return "home";
    }
}

 

@Controller : 어노테이션을 붙이면 servlet-context.xml에서 이것을 인식하여 컨트롤러로 등록함.

@RequestMapping : 스프링은 HandlerMppaing에 의해 컨트롤러가 결정된다. 이 컨트롤러에서 HandlerAdapter에 의해 실행 메서드가 결정되는 데 @RequestMapping 어노테이션이 그 정보를 제공해 준다. value에 해당하는 url이 GET 방식으로 요청이 들어올 때 해당 메서드를 실행한다.

home 메서드는 serverTime이라는 속성을 Model에 추가하고 이 값은 formattedDate 변수 안에 담긴 현재 날짜 정보를 담고 있다. 이 정보는 JSP에서 클라이언트에게 전달할 HTML 문서를 만들 때 쓰인다. 여기서 모델은 어떤 구조화된 데이터를 담는 객체라고 보면 된다.

마지막으로 "home" 문자열을 반환하는 데 이 문자열은 나중에 servlet-context.xml에 설정된 prefix와 suffix 정보를 참조하여 /WEB-INF/views/home.jsp 파일을 찾는 정보를 제공한다.

 

 

 

[Spring] Annotation 정리

 

Annotation 이란?

Annotation(@)은 사전적 의미로는 주석이라는 뜻이다.
자바에서 Annotation은 코드 사이에 주석처럼 쓰이며 특별한 의미, 기능을 수행하도록 하는 기술이다.
즉, 프로그램에게 추가적인 정보를 제공해주는 메타데이터 라고 볼 수 있다.
meta data : 데이터를 위한 데이터)

다음은 어노테이션의 용도를 나타낸 것이다.

컴파일러에게 코드 작성 문법 에러를 체크하도록 정보를 제공한다.

소프트웨어 개발 툴이 빌드나 배치시 코드를 자동으로 생성할 수 있도록 정보를 제공한다.

실행시(런타임시)특정 기능을 실행하도록 정보를 제공한다.

기본적으로 어노테이션을 사용하는 순서는 다음과 같다.

  1. 어노테이션을 정의한다.
  2. 클래스에 어노테이션을 배치한다.
  3. 코드가 실행되는 중 Reflection을 이용하여 추가 정보를 획득하여 기능을 실시한다.

@RestController

Spring에서 Controller 중 View로 응답하지 않는, Controller를 의미한다.

method의 반환 결과를 JSON 형태로 반환한다.

이 Annotation이 적혀있는 Controller의 method는 HttpResponse로 바로 응답이 가능하다.
@ResponseBody 역할을 자동적으로 해주는 Annotation이다.
@Controller + @ResponseBody를 사용하면 @ResponseBody를 모든 메소드에서 적용한다.

 

@RequestMapping

요청 URL을 어떤 method가 처리할지 mapping해주는 Annotation이다.

Controller나 Controller의 method에 적용한다.

요청을 받는 형식인 GET, POST, PATCH, PUT, DELETE 를 정의하기도 한다.

요청 받는 형식을 정의하지 않는다면, 자동적으로 GET으로 설정된다.

@RequestMapping("/list"), @RequestMapping("/home, /about"); @RequestMapping("/admin", method=RequestMethod.GET)@Controller // 1) Class Level //모든 메서드에 적용되는 경우 “/home”로 들어오는 모든 요청에 대한 처리를 해당 클래스에서 한다는 것을 의미 @RequestMapping("/home") public class HomeController { /* an HTTP GET for /home */ @RequestMapping(method = RequestMethod.GET) public String getAllEmployees(Model model) { ... } /* 2) Handler Level 요청 url에 대해 해당 메서드에서 처리해야 되는 경우 “/home/employees” POST 요청에 대한 처리를 addEmployee()에서 한다는 것을 의미한다. value: 해당 url로 요청이 들어오면 이 메서드가 수행된다. method: 요청 method를 명시한다. 없으면 모든 http method 형식에 대해 수행된다. */ /* an HTTP POST for /home/employees */ @RequestMapping(value = "/employees", method = RequestMethod.POST) public String addEmployee(Employee employee) { ... } }

@RequestMapping에 대한 모든 매핑 정보는 Spring에서 제공하는 HandlerMapping Class가 가지고 있다.

 

@Autowired

속성(field), setter method, constructor(생성자)에서 사용하며 Type에 따라 알아서 Bean을 주입 해준다.
무조건적인 객체에 대한 의존성을 주입시킨다.
 Annotation을 사용할 시, 스프링이 자동적으로 값을 할당한다.
Controller 클래스에서 DAO나 Service에 관한 객체들을 주입 시킬 때 많이 사용한다.

필드, 생성자, 입력 파라미터가 여러 개인 메소드(@Qualifier는 메소드의 파라미터)에 적용 가능하다.

Type을 먼저 확인한 후 못 찾으면 Name에 따라 주입한다.
Name으로 강제하는 방법: @Qualifier을 같이 명시

Bean을 주입받는 방식 (3가지)

  1. @Autowired
  2. setter
  3. 생성자 (@AllArgsConstructor 사용) -> 권장방식

@GetMapping

@RequestMapping(Method=RequestMethod.GET)과 같다.
@PostMapping, @PutMapping, @PatchMapping, @DeleteMapping 등 도 있다.

@RequestParam

@PathVariable과 비슷하다.
request의 parameter에서 가져오는 것이다. method의 파라미터에 사용된다.
?moviename=thepurge 와 같은 쿼리 파라미터를 파싱해준다.

HTTP GET 요청에 대해 매칭되는 request parameter 값이 자동으로 들어간다.
url 뒤에 붙는 parameter 값을 가져올 때 사용한다.

http://localhost:8080/home?index=1&page=2

@GetMapping("/home") public String show(@RequestParam("page") int pageNum { }

위의 경우 GET /home?index=1&page=2와 같이 uri가 전달될 때 page parameter를 받아온다.
@RequestParam 어노테이션의 괄호 안의 문자열이 전달 인자 이름(실제 값을 표시)이다.

@RequestMapping(value = "/search/movie", method = RequestMethod.GET) public ResponseEntity<?> someMethod(@RequestParam String moviename) { // request URI would be like '/search/movie?moviename=thepurge' try { List<Movie> movies = service.searchByMoviename(moviename); } catch(Exception e) { e.printStackTrace(); } // return some response here }

@RequestBody

요청이 온 데이터(JSON이나 XML형식)를 바로 Class나 model로 매핑하기 위한 Annotation이다.

POST나 PUT, PATCH로 요청을 받을때에, 요청에서 넘어온 body 값들을 자바 타입으로 파싱해준다.

HTTP POST 요청에 대해 request body에 있는 request message에서 값을 얻어와 매핑한다.
RequestData를 바로 Model이나 클래스로 매핑
한다.

이를테면 JSON 이나 XML같은 데이터를 적절한 messageConverter로 읽을 때 사용하거나 POJO 형태의 데이터 전체로 받는 경우에 사용한다.

@RequestMapping(value = "/book", method = RequestMethod.POST) public ResponseEntity<?> someMethod(@RequestBody Book book) { // we can use the variable named book which has Book model type. try { service.insertBook(book); } catch(Exception e) { e.printStackTrace(); } // return some response here }

@Data

@Getter @Setter @EqualsAndHashCode @AllArgsConstructor을 포함한 Lombok에서 제공하는 필드와 관련된 모든 코드를 생성한다.

실제로 사용하지 않는것이 좋다.
전체적인 모든 기능 허용으로 위험 존재

 

@Slf4j어노테이션

클래스를 생성할 때마다 항상 로그를 남기기 위해 Logger 변수를 선언해야 했는데 Lombok의 @Slf4j 어노테이션을 사용하면 편하게 사용할 수 있습니다.


Controller에서 쓸 DTO 클래스란??

Request와 Response용 DTO는 View를 위한 클래스로, 자주 변경이 필요한 클래스이다.
Entity 클래스와 DTO 클래스를 분리하는 이유 View Layer와 DB Layer를 철저하게 역할 분리하기 위해서다.

테이블과 매핑되는 Entity 클래스가 변경되면 여러 클래스에 영향을 끼치게 되는 반면 View와 통신하는 DTO 클래스(Request/ Response 클래스)는 자주 변경되므로 분리해야 한다.

 

Spring 개념

spring은 개발 할 때 사용하는 Framework입니다.
한국어로 번역하면 Frame은 틀 Work는 일이므로 일(개발)을 효율적으로 하기위해서 사용하는 틀이라고 할 수 있습니다.
 framework는 정해진 규칙을 지키면 개발의 생산성을 향상 시킬 수 있는 특징이 있습니다.

일상생활에 비유하자면 커피를 만들 때 핸드 드립으로 만드는 것은 시간과 정성이 많이 소모되지만, 커피머신으로 커피를 만든다면 간단한 버튼 조작 만으로 빠르게 커피를 만들 수 있습니다.

여기서 커피를 만들기 위해 커피머신이 하는 역할이 Spring Framework와 유사합니다.

프레임워크 중에서도 스프링 프레임워크는 자바 플랫폼을 위한 오픈소스 애플리케이션 프레임워크로서 엔터프라이즈급 애플리케이션을 개발하기 위한 모든 기능을 종합적으로 제공하는 경량화된 솔루션입니다.

여기서 엔터프라이즈급 개발이란 뜻대로만 풀이하면 기업을 대상으로 하는 개발이라는 말입니다.
즉, 대규모 데이터 처리와 트랜잭션이 동시에 여러 사용자로부터 행해지는 매우 큰 규모의 환경을 엔터프라이즈 환경이라 일컫습니다.

Spring Framework는 경량 컨테이너로 자바 객체를 담고 직접 관리합니다. 객체의 생성 및 소멸 그리고 라이프 사이클을 관리하며 언제든 Spring 컨테이너로부터 필요한 객체를 가져와 사용할 수 있습니다.

Spring Framework는 경량 컨테이너, 제어 역행, 의존성 주입 등 다양한 특징을 가지고 있습니다. 

저희는 그 중에서도 MVC구조에 대해 주목해 볼 것 입니다.

MVC란 (Model, View ,Controller) 구조를 통해 사용자 인터페이스와 비지니스 로직을 분리하여 개발 하는 것을 의미합니다.

Model

Model은 MVC 패턴안에서 데이터처리를 담당하는 부분입니다. Model부분은 Service영역과 DAO영역으로 나누어져 있습니다.

DAO는 단일 데이터 접근 로직으로서 DB의 요청과 결과를 받는 로직이고.
Service는 여러개의 DAO를 묶은 트랜잭션의 단위를 뜻합니다.

View

View는 사용자 Interface를 담당하며 사용자에게 보여지는 부분입니다. 

JSP나 Vue와 같은 것이 이 예입니다. 

View는 Controller를 통해 모델에 데이터에 대한 시각화를 담당하며 

View는 자신이 요청을 보낼 Controller의 정보만 알고 있어야 하는 것이 핵심이다.

Controller

Controller에서는 View에 받은 요청을 가공하여 Model (Service 영역)에 이를 전달한다. 

또한 Model로 부터 받은 결과를 View로 넘겨주는 역할을 합니다. 

Controller에서는 모든 요청 에러와 모델 에러를 처리하며 View와 Controller에 정보를 알고 있어야 합니다.

  • DTO 란 : 

계층간 데이터 교환을 위한 자바 빈즈를 말한다. 여기서 말하는 계층간의

컨트롤러, 뷰, 비즈니스 계층, 퍼시스턴스 계층을 말하며 각 계층간 데이터 교환을 위한 객체를 DTO 또는 VO라고 부른다.

 

728x90

'Be Smart > Spring' 카테고리의 다른 글

Spring Boot Validation  (0) 2021.09.07
스프링의 핵심  (0) 2021.09.06
Spring Boot  (0) 2021.09.06
Web 개론  (0) 2021.09.06
Singleton Pattern  (0) 2021.08.20

댓글