[spring] mvc 핵심 구성 요소

굿거리·2023년 4월 26일
0


(출처 : https://pangtrue.tistory.com/83)

  • Spring Bean
    스프링의 IOC가 직접 관리하는 객체를 의미한다. Bean으로 설정하는 방법에는 XML을 통해 등록하는 방법과 클래스에 Annotation으로 등록하는 방법, Config 파일에 Annotation으로 등록하는 방법 등이 있다.

  • DispatcherServlet
    DispatcherServlet은 모든 연결을 담당한다. 웹 브라우저로부터 요청이 들어오면 DispatcherServlet은 그 요청을 처리하기 위한 컨트롤러 객체를 검색한다. 이 때 DispatcherServlet은 직접 컨트롤러를 검색하지 않고 HanlderMapping이라는 빈 객체에게 컨트롤러 검색을 요청한다.

  • HandlerMapping
    HandlerMapping은 클라이언트의 요청 경로를 이용해서 이를 처리할 컨트롤러 빈 객체를 DispatcherServlet에 전달한다. 예를 들어 웹 요청 경로가 '/hello'라면 등록된 컨트롤러 빈 중에서 '/hello' 요청 경로를 처리할 컨트롤러를 리턴한다.

  • HandlerAdapter
    컨트롤러 객체를 DispatcherServlet이 전달받았다고 해서 바로 컨트롤러 객체의 메서드를 실행할 수 있는 것은 아니다. DispatcherServlet은 @Controller 어노테이션을 이용해서 구현한 컨트롤러뿐만 아니라 Controller 인터페이스를 구현한 컨트롤러, 그리고 특수 목적으로 사용되는 HttpRequestHandler 인터페이스를 구현한 클래스를 실행할 수 있다. @Controller, Controller 인터페이스, HttpRequestHandler 인터페이스를 동일한 방식으로 처리하기 위해 사용되는 것이 HandlerAdapter이다.

Controller? Handler?

클라이언트의 요청을 실제로 처리하는 것은 컨트롤러이고 DispatcherServlet은 클라이언트의 요청을 전달받는 창구 역할을 한다. DispatcherServlet은 클라이언트의 요청을 처리할 컨트롤러를 찾기 위해 HandlerMapping을 사용한다. 여기서 왜 이름이 ControllerMapping이 아닌 HandlerMapping일까?

보통 @Controller 어노테이션을 붙인 클래스를 이용하지만, 원한다면 자신이 직접 만든 클래스를 이용해서 클라이언트의 요청을 처리할 수도 있다. 즉 DispatcherServlet 입장에서는 클라이언트 요청을 처리하는 객체의 타입이 반드시 @Controller를 적용한 클래스일 필요는 없다. 위에서 언급된 HttpRequestHandler가 존재하는 것처럼.

이런 이유로 스프링 MVC는 웹 요청을 실제로 처리하는 객체를 핸들러(Handler)라고 표현하고 있으며 @Controller 적용 객체나 Controller 인터페이스를 구현한 객체는 모두 스프링 MVC 입장에서는 핸들러가 된다. 따라서 특정 요청 경로를 처리해주는 핸들러를 찾아주는 객체를 HandlerMapping이라고 부른다.

DispatcherServlet과 Container


(출처 : https://m.blog.naver.com/thwlstmxk/221125541685)

DispatcherServlet은 전달받은 설정 파일을 이용해서 스프링 컨테이너를 생성하는데 HandlerMapping, HandlerAdapter, 컨트롤러, ViewResolver 등의 빈은 위처럼 DispatcherServlet이 생성한 컨테이너에서 구한다. 따라서 DispatcherServlet이 사용하는 설정 파일에 이들 빈에 대한 정의가 포함되어있어야 한다.

@Controller를 위한 HandlerMapping과 HandlerAdapter

@Controller 적용 객체는 DispatcherServlet 입장에서 보면 한 종류의 핸들러 객체이다. DispatcherServlet은 HandlerMapping과 HandlerAdapter 빈을 사용하므로 핸들러에 알맞는 HandlerMapping 빈과 HandlerAdapter 빈이 스프링 설정에 등록되어있어야 한다.

@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {

	@Override
    public void configureDefaultServletHandling(
    		DefalutSercletHandlerConfigurer configurer) {
        configurer.enable();
        
    @Override
    public void configurerViewResolvers(ViewResolverReigistry registry) {
    	registry.jsp("/WEB-INF/view/", ".jsp");
    }
}

위에서 @EndableWebMvc라는 어노테이션이 있는데, 이 태그가 빈으로 추가해주는 클래스 중에는 @Controller 타입의 핸들러 객체를 처리하기 위한 다음의 두 클래스도 포함되어있다.

org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
  • RequestMappingHandlerMapping은 @Controller 어노테이션이 적용된 객체의 요청 매핑 어노테이션인 @GetMapping 값을 이용해서 요청을 처리할 컨트롤러 빈을 찾는다.

  • RequestMappingHandlerAdapter는 컨트롤러의 메서드를 알맞게 실행하고 그 결과를 ModelAndView 객체로 변환해서 DispatcherServlet에 리턴한다.

@Controller
public class HelloController {
	
    @RequestMapping("/hello")
    public String hello(Model model, @RequestParam(value="name", required="false") String name) {
    	....
    	model.addAttribute("a", a);
        return "hello";
    }
}

RequestMappingHandlerAdapter 클래스는 "/hello" 요청 경로에 대해 hello() 메서드를 호출한다. 이 때 Model 객체를 생성해서 첫 번째 파라미터로 전달한다. 비슷하게 이름이 "name"인 HTTP 요청 파라미터의 값을 두 번째 파라미터로 전달한다.

  • viewResolver
    HandlerAdapter로부터 컨트롤러의 요청 처리 결과를 ModelAndView로 받으면 DispatcherServlet은 겨로가를 보여줄 뷰를 찾기 위해 ViewResolver 빈 객체를 사용한다. ModelAndView는 컨트롤러가 리턴한 뷰 이름을 담고 있는데 ViewResolver는 이 뷰 이름에 해당하는 View 객체를 찾거나 생성해서 리턴한다.
profile
개발자를 향해

0개의 댓글