[ Computer Science ]/프로그래밍 이론

[Spring Boot] DispatcherServlet - 스프링부트의 동작 구조

2024. 1. 22. 00:45
목차
  1. 스프링 부트의 동작 구조
  2. Dispatcher Servlet 이란?
  3. DispatcherServlet의 동작
  4. HandlerMapping, HandlerAdapter 자동 등록
  5. DispatcherServlet 
  6. doDispatch()
  7. View를 사용하는 방법과 REST방식의 차이 (코드)
  8. @Controller 방식 응답
  9. @RestController 방식 응답

스프링 부트의 동작 구조


스프링 부트의 기본 의존성 중 하나인 spring-boot-starter-web 모듈을 사용하면,

기본적으로 내장 톰캣(Tomcat)을 사용하는 스프링 MVC 구조를 기반으로 동작한다.

 

클라이언트의 요청이 들어오면 서블릿이 이를 처리해야 하는데, 서블릿은 서블릿 컨테이너에서 관리하고,

톰캣이 서블릿 컨테이너의 역할과 WAS(Web Application Server)의 역할을 담당한다.

서블릿(Servlet)은 클라이언트의 요청을 처리하고, 결과를 반환하는 자바의 웹 프로그래밍 기술이다.

서블릿 컨테이너의 특징

  • 서블릿 객체를 생성, 초기화, 호출, 종료하는 생명주기를 관리한다.
  • 서블릿 객체는 싱글톤 패턴으로 관리된다.
  • 멀티 스레딩을 지원한다.

 


 

Dispatcher Servlet 이란?

스프링에서는 DispatcherServlet이 서블릿의 역할을 담당한다.

클라이언트의 요청을 받아서 서블릿 컨테이너에서 관리되는 DispatcherServlet이 요청을 처리하고 반환하는 것이다.

 

DispatcherServlet의 동작

1. 클라이언트 요청

클라이언트에서 요청(HttpServletRequest)이 들어오면, 서블릿 컨테이너는 DispatcherServlet으로 이를 전달한다.

2. Handler 조회

DispatcherServlet은 핸들러 매핑(HandlerMapping)을 통해 요청 URI에 매핑된 핸들러(Controller)를 탐색한다.

3. Handler Adapter 조회

조회한 핸들러를 실행할 수 있는 핸들러 어댑터를 조회한다.

4. Handler Adapter 실행

핸들러 어댑터(HandlerAdapter)를 통해 핸들러(Controller)를 호출한다.

5. Handler(Controller) 실행

핸들러(Controller)를 실행하여 컨트롤러에서 요청을 처리하고, 응답을 다시 핸들러 어댑터로 반환한다.

6. ModelAndView 반환

핸들러 어댑터는 이 응답을 ModelAndView로 가공하여 반환한다.

7-1. @Controller 사용 시 

1) View Resolver를 찾고 실행한다.

2) View Resolver는 View의 논리 이름을 물리 이름으로 바꾸고, 랜더링 역할을 담당하는 View 객체를 반환한다.

3) View를 랜더링 하여 클라이언트에 반환한다.

7-2. @RestController 사용 시 

1) View와 ViewResolver를 거치지 않는다.

2) Controller로 부터 반환 받은 데이터를 MessageConverter를 거쳐서 Json 형식으로 변환한다.

3) Json을 ResponseBody로 응답한다.


뷰 리졸버를 사용하는 방식

 

REST API 방식 (MessageConverter)

 


HandlerMapping, HandlerAdapter 자동 등록

SpringBoot가 핸들러 매핑과 핸들러 어댑터를 자동으로 등록해준다.

HandlerMapping

1순위 : RequestMappingHandlerMapping

- @RequestMapping 을 보고 자동으로 매핑해준다.

2순위 : BeanNameUrlHandlerMapping

- Spring Bean 이름으로 핸들러를 찾아서 매핑한다.

HandlerAdapter

1순위 : RequestMappingHandlerMapping

- @RequestMapping 을 보고 자동으로 매핑해준다.

2순위 : HttpRequestHandlerAdapter

- HttpRequestHandler 처리

 


DispatcherServlet 

부모 클래스에서 HttpServlet을 상속받아서 사용하고, Servlet으로 동작한다.

SpringBoot는 DispatcherServlet을 이용하여 모든 경로( urlPatterns="/" )에 대해 매핑한다. 

 


doDispatch()

DispatcherServlet의 핵심이다.

 

> IntelliJ에서 doDispatch() 검색 방법

SpringBoot를 사용하는 프로젝트 어디서나 Ctrl + Shift + f로 검색창을 열어서 "범위(S)"를 선택한 뒤 doDispatch를 검색하면 찾을 수 있다.
더보기

 

정상 진행 로직 이외에 예외 처리 등은 생략하였음.

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
		HttpServletRequest processedRequest = request;
		HandlerExecutionChain mappedHandler = null;
        
        ModelAndView mv = null;
        Exception dispatchException = null;
        
        //핸들러 조회 Determine handler for the current request.
        mappedHandler = getHandler(processedRequest);
        if (mappedHandler == null) {
        	noHandlerFound(processedRequest, response);
       		return;
        }
        //핸들러 어댑터 조회 Determine handler adapter for the current request.
        HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
        
        //실제로 핸들러 어댑터 실행 Actually invoke the handler.
        mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
        //-> ModelAndView 반환
        
        //doDispatch() 정상 진행
        processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

}
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
			@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
			@Nullable Exception exception) throws Exception {
	//생략
    //뷰 랜더링 호출
    render(mv, request, response);
}
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
		View view;
		String viewName = mv.getViewName();
	//뷰 리졸버를 통해서 뷰 찾아서 뷰 반환
		view = resolveViewName(viewName, mv.getModelInternal(), locale, request);
	//뷰 렌더링
		view.render(mv.getModelInternal(), request, response);
}

 


View를 사용하는 방법과 REST방식의 차이 (코드)


@Controller 방식 응답

@Controller
public class ViewController {

    @Autowired
    private MyService myService;
    
    static class ResponseObj{
        private int num;
        private String msg;
        //생성자 생략
    }

    @GetMapping("/view")
    public String useViewResolver(Model model){
        ResponseObj resp = new ResponseObj(1, myService.getHello());
        model.addAttribute("obj", resp);
        return "home";
    }
}

위와 같이 model.addAttribute 메서드를 이용하여 model에 객체를 담으면,

ViewResolver가 해당 객체를 View에 담아 응답한다.

 


 

@RestController 방식 응답

@RestController
public class RestApiController {

    @Autowired
    private MyService myService;

    static class ResponseObj{
        private int num;
        private String msg;
        //생성자 생략
    }
    
    @GetMapping("/rest")
    public ResponseEntity<?> useViewResolver(){
        ResponseObj resp = new ResponseObj(1, myService.getHello());

        return ResponseEntity.ok(resp);
    }
}

위와 같이 반환하고자 하는 객체를 그대로 반환한다.

ResponseEntity 클래스는 객체를 JSON으로 변환하여 응답해 준다.

 


 

이 글은 '스프링 부트 핵심 가이드' 책을 참고하여 썼습니다.
반응형
저작자표시 (새창열림)

'[ Computer Science ] > 프로그래밍 이론' 카테고리의 다른 글

[CS] 객체지향 4대 특성(캡슐화, 상속, 다형성, 추상화)  (0) 2024.02.02
[Computer Science/디자인 패턴] 전략 패턴(strategy pattern)  (0) 2024.01.25
[Spring / 스프링 부트 핵심 가이드] 디자인 패턴 정리  (0) 2023.10.01
[ComputerScience / 디자인 패턴] 브릿지 패턴(Bridge Pattern, 가교 패턴)  (0) 2023.10.01
[Spring / 스프링 부트 핵심 가이드] 레이어드 아키텍처, SpringMVC  (0) 2023.10.01
  1. 스프링 부트의 동작 구조
  2. Dispatcher Servlet 이란?
  3. DispatcherServlet의 동작
  4. HandlerMapping, HandlerAdapter 자동 등록
  5. DispatcherServlet 
  6. doDispatch()
  7. View를 사용하는 방법과 REST방식의 차이 (코드)
  8. @Controller 방식 응답
  9. @RestController 방식 응답
'[ Computer Science ]/프로그래밍 이론' 카테고리의 다른 글
  • [CS] 객체지향 4대 특성(캡슐화, 상속, 다형성, 추상화)
  • [Computer Science/디자인 패턴] 전략 패턴(strategy pattern)
  • [Spring / 스프링 부트 핵심 가이드] 디자인 패턴 정리
  • [ComputerScience / 디자인 패턴] 브릿지 패턴(Bridge Pattern, 가교 패턴)
HSRyuuu
HSRyuuu
Web Backend Developer happyhsryu
HSRyuuu
HS_dev_log
HSRyuuu
전체
오늘
어제
  • 전체 글 보기 (230)
    • Java (24)
    • Spring (25)
    • JPA & QueryDSL (13)
    • Database (17)
    • 자료구조 & 알고리즘 (30)
    • DevOps (10)
    • [ Computer Science ] (47)
      • Web & Network (14)
      • 프로그래밍 이론 (11)
      • 운영체제 (3)
      • 데이터베이스 이론 (5)
      • Linux 리눅스 (7)
    • [ Frontend ] (16)
      • Vue.js & Nuxt.js (8)
      • JSP_Thymeleaf (7)
    • [ 기타 ] (48)
      • 오픈소스 라이브러리 (5)
      • 코딩테스트 (13)
      • Trouble Shooting (7)
      • Tech Interview (6)
      • Book Review (9)
      • 끄적끄적... (6)
      • 개인 프로젝트 (2)

블로그 메뉴

  • 홈
  • 태그
  • github

공지사항

  • GitHub
  • 공부한 내용을 정리하고 기록하는 블로그 입니다.

인기 글

태그

  • cleancode
  • 백엔드기술면접
  • 백엔드공부
  • HTTP
  • 트랜잭션
  • Redis
  • vue3
  • Redisson
  • SpringBoot
  • Linux
  • 리눅스
  • MySQL
  • Spring
  • 백엔드스쿨
  • 제로베이스
  • 클린코드
  • 자료구조
  • 백엔드
  • 기술면접
  • 개발자
  • JPA
  • mybatis
  • SQL
  • Nuxt3
  • web
  • Java
  • Database
  • TechInterview
  • 백준
  • springsecurity

최근 댓글

최근 글

hELLO · Designed By 정상우.
HSRyuuu
[Spring Boot] DispatcherServlet - 스프링부트의 동작 구조
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.