이 영역을 누르면 첫 페이지로 이동
시간의화살 블로그의 첫 페이지로 이동

시간의화살

페이지 맨 위로 올라가기

시간의화살

행복하세요

[Spring Basic] DispatcherServlet

  • 2022.06.23 13:43
  • Spring/Spring

 

 

 

 

 

스프링 MVC의 디스패처 서블릿은 여러 개의 서블릿들에 대해 공통 부분을 따로 빼서 처리하는 역할을 수행한다. (프론트 컨트롤러)

 

클라이언트로부터 요청이 오면 우선 디스패처 서블릿이 요청을 받아 해당하는 컨트롤러의 메서드를 호출한 후 컨트롤러가 반환하는 뷰 이름을 받아오는 방식으로 진행된다.

이 과정에서 URL을 키, 메서드를 값으로 가지는 HandlerMapping과 HandlerAdapter가 사용된다.

 

HandlerMapping은 디스패처 서블릿이 클라이언트로부터 받은 요청을 어떤 컨트롤러가 처리할 지 결정한다.

HandlerAdapter는 HandlerMapping이 찾은 컨트롤러를 실행하고 그 결과를 적당한 객체로 변환한다. 

 

요청이 왔을 때 디스패처 서블릿은 HandlerMapping에게 먼저 물어본 후 메서드를 호출하고, 해당하는 메서드는 어떤 HandlerAdapter가 호출할 수 있는지 확인한다.

 

 

 

 

 

 

ViewResolver는 실제 뷰 이름을 가져올 때 사용한다.

ViewResolver를 통해 실제 뷰 이름을 가져오고, 디스패처 서블릿은 뷰 이름을 바탕으로 registerForm에게 모델을 전달한다

 

 

public class DispatcherServlet extends FrameworkServlet {
    public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver";	
	public static final String LOCALE_RESOLVER_BEAN_NAME = "localeResolver";	
	public static final String THEME_RESOLVER_BEAN_NAME = "themeResolver";
    
    ...
    
    private void initHandlerMappings(ApplicationContext context) {
		this.handlerMappings = null;

		if (this.detectAllHandlerMappings) {
			// Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
			Map<String, HandlerMapping> matchingBeans =
					BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
			if (!matchingBeans.isEmpty()) {
				this.handlerMappings = new ArrayList<>(matchingBeans.values());
				// We keep HandlerMappings in sorted order.
				AnnotationAwareOrderComparator.sort(this.handlerMappings);
			}
		}
		else {
			try {
				HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
				this.handlerMappings = Collections.singletonList(hm);
			}
			catch (NoSuchBeanDefinitionException ex) {
				// Ignore, we'll add a default HandlerMapping later.
			}
		}

		// Ensure we have at least one HandlerMapping, by registering
		// a default HandlerMapping if no other mappings are found.
		if (this.handlerMappings == null) {
			this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
			if (logger.isTraceEnabled()) {
				logger.trace("No HandlerMappings declared for servlet '" + getServletName() +
						"': using default strategies from DispatcherServlet.properties");
			}
		}

		for (HandlerMapping mapping : this.handlerMappings) {
			if (mapping.usesPathPatterns()) {
				this.parseRequestPath = true;
				break;
			}
		}
	}

	/**
	 * Initialize the HandlerAdapters used by this class.
	 * <p>If no HandlerAdapter beans are defined in the BeanFactory for this namespace,
	 * we default to SimpleControllerHandlerAdapter.
	 */
	private void initHandlerAdapters(ApplicationContext context) {
		this.handlerAdapters = null;

		if (this.detectAllHandlerAdapters) {
			// Find all HandlerAdapters in the ApplicationContext, including ancestor contexts.
			Map<String, HandlerAdapter> matchingBeans =
					BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
			if (!matchingBeans.isEmpty()) {
				this.handlerAdapters = new ArrayList<>(matchingBeans.values());
				// We keep HandlerAdapters in sorted order.
				AnnotationAwareOrderComparator.sort(this.handlerAdapters);
			}
		}
		else {
			try {
				HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class);
				this.handlerAdapters = Collections.singletonList(ha);
			}
			catch (NoSuchBeanDefinitionException ex) {
				// Ignore, we'll add a default HandlerAdapter later.
			}
		}

		// Ensure we have at least some HandlerAdapters, by registering
		// default HandlerAdapters if no other adapters are found.
		if (this.handlerAdapters == null) {
			this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);
			if (logger.isTraceEnabled()) {
				logger.trace("No HandlerAdapters declared for servlet '" + getServletName() +
						"': using default strategies from DispatcherServlet.properties");
			}
		}
	}

}

 

위의 소스코드는 실제 DispatcherServlet.java의 일부이다.

HandlerMapping과 HandlerAdapter를 사용해 컨트롤러를 찾고 실행함을 확인할 수 있다.

 

스프링 MVC 에서는 일반적으로 서블릿으로 디스패처 서블릿 하나만 사용해 리소스를 효과적으로 관리한다.

 

 

반응형

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

[Spring Basic] JUnit Test Framework  (0) 2022.07.09
[Spring Basic] 파라미터의 변환과 검증  (0) 2022.06.24
[Spring Basic] 리다이렉트와 포워드  (0) 2022.05.12
[Spring Basic] 서블릿과 JSP  (0) 2022.05.05
[Spring Basic] 서블릿과 출력  (0) 2022.04.13

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • [Spring Basic] JUnit Test Framework

    [Spring Basic] JUnit Test Framework

    2022.07.09
  • [Spring Basic] 파라미터의 변환과 검증

    [Spring Basic] 파라미터의 변환과 검증

    2022.06.24
  • [Spring Basic] 리다이렉트와 포워드

    [Spring Basic] 리다이렉트와 포워드

    2022.05.12
  • [Spring Basic] 서블릿과 JSP

    [Spring Basic] 서블릿과 JSP

    2022.05.05
다른 글 더 둘러보기

정보

시간의화살 블로그의 첫 페이지로 이동

시간의화살

  • 시간의화살의 첫 페이지로 이동

검색

방문자

  • 전체 방문자
  • 오늘
  • 어제

카테고리

  • 분류 전체보기 (590) N
    • Algorithm (205)
      • Data Structure (5)
      • Theory && Tip (33)
      • Baekjoon (166)
      • ALGOSPOT (1)
    • Spring (123)
      • Spring (28)
      • Spring Web MVC (20)
      • Spring Database (14)
      • Spring Boot (6)
      • Spring 3.1 (11)
      • Spring Batch (6)
      • Spring Security (16)
      • JPA (12)
      • Spring Data JPA (5)
      • QueryDSL (4)
      • eGovFramework (1)
    • Programming Language (74)
      • Java (19)
      • C (25)
      • C++ (12)
      • JavaScript (15)
      • Python (1)
      • PHP (2)
    • Computer Science (53) N
      • System Programming (22)
      • Computer Architecture (4)
      • Computer Network (13)
      • Operating System (10) N
      • Universial Programming Lang.. (4)
    • Database (21)
      • MySQL (3)
      • Oracle (3)
      • Database (7)
      • Redis (5)
      • Elasticsearch (3)
    • DevOps (20)
      • Docker && Kubernetes (8)
      • Jenkins (4)
      • Github Actions (0)
      • Amazon Web Service (8)
    • Machine Learning (28)
      • AI Introduction (28)
    • Mobile (28)
      • Android (21)
      • Flutter (7)
    • FastAPI (3)
      • FastAPI (3)
    • Web (21)
      • HTML && CSS (14)
      • Web Scraping (7)
    • Solutions (13)
    • etc.. (1)
      • Notice (1)

최근 글

나의 외부 링크

메뉴

  • 홈

정보

13months의 시간의화살

시간의화살

13months

블로그 구독하기

  • 구독하기
  • RSS 피드

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기
Powered by Tistory / Kakao. Copyright © 13months.

티스토리툴바