Java/JavaSpring

Chap 10. 스프링 MVC 프레임워크 동작 방식

펭킹 2022. 7. 6. 17:54

스프링 MVC 핵심 구성요소

 

다음그림은 스프링 MVC모델 처리 순서이다. 아래 설명과 참조하면서 흐름을 보면 좋다.

 

 

<<spring bean>>이라고 표시한 것은 스프링 빈으로 등록해야되는 요소이다.

DispatcherServlet은 모든 연결을 담당한다. 사용자에게 전달 받은 요청을 HandlerMapping이라는 빈 객체 컨트롤러에게 검색을 요청한다.

HandlerMapping은 요청경로를 받아서 처리한다. 예를 들어 요청경로가 "/hello" 일 때 DispatcherServlet으로 "/hello" 요청경로를 처리할 컨트롤러를 리턴한다.

HandlerAdapter는 DispatcherServlet에서 요청받은 컨트롤러에 알맞은 메서드를 호출하여 요청처리를 처리하여 그 결과를 DispatcherServlet에 리턴한다. 이때 요청 처리결과는 ModelandView 이다.

ViewResolver는 DispatcherServlet에서 view 처리를 위해 찾는 빈 객체이다.

 

클라이언트 요청(request)의 실제처리는 컨트롤러가 담당하고, DispatcherServlet 는 컨트롤러 안내자 역할을 한다.

스프링 MVC는 범용 프레임워크이고, 직접 만든 클래스로 클라이언트 요청을 처리 할 수 있다. 스프링이 클라이언트 요청을 처리하기 위해 HttpRequestHandler라는 타입도 존재한다.

 

DispatcherServlet과 스프링 컨테이너

 

DispatcherServlet은 스프링 컨테이너를 생성하고 그 컨테이너로 부터 필요한 빈객체를 구한다. DispatcherServlet은 스프링 컨테이너에서 빈으로 등록된 HandlerMapping, HandlerAdapter, 컨트롤러 빈, ViewResolver를 구해서 사용하므로 위 항목들은 빈으로 정의되어야 한다.

 

RequestMappingHandlerMapping은 요청 매핑 어노테이션 값을 이용해서 처리할 컨트롤러 빈을 찾는다.

 

@Controller
public class HelloController {

	@RequestMapping("/hello")
	public String hello(Model model, @RequestParam(value="name",required = false)String name)
	{
		model.addAttribute("greeting","안녕하세요, "+name);
		return "hello";
	}
}

 

RequestMappingHandlerAdapter 는 컨트롤러 메서드 결과 값이 String 타입이면 해당 값을 뷰 이름으로 갖는 ModelandView 객체를 생성하여 DispatcherServlet에 리턴한다.

 

WebMvcConfigurer 인터페이스와 설정

@EnableWebMvc 애노테이션 사용 시 @Controller 애노테이션을 붙인 컨트롤러를 위한 설정을 생성해야한다.

 

JSP를 위한 ViewResolver

 

@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {

	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		registry.jsp("/WEB-INF/view/", ".jsp");
	}

}

 

registry 파라미터를 통해 jsp메서드를 사용시 jsp를 위한 ViewResolver를 설정할 수 있다.

 

@Controller
public class HelloController {

	@RequestMapping("/hello")
	public String hello(Model model, @RequestParam(value="name",required = false)String name)
	{
		model.addAttribute("greeting","안녕하세요, "+name);
		return "hello";
	}
}

 

Model에 담긴 값은 View 객체에 Map 형식(key & value)으로 전달 된다. InternalResourceView는 Map 객체에 담겨 있는 키 값을 request.setAttribute()를 이용해서 request의 속성에 저장한다. 컨트롤러에서 지정한 Model 속성은 request 객체 속성으로 jsp에 전달되기 때문에 jsp는 다음과 같이 모델에 지정한 속성이름을 사용하여 값을 사용한다.

 

인사말 : ${greeting}

 

디폴트 핸들러와 HandlerMapping의 우선순위

 

web.xml설정에서 DispatcherServlet에 대한 매핑을 '/'로 설정했다.

 

<servlet>
   <servlet-name>dispatcher</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   ...
</servlet>

<servlet-mapping>
   <servlet-name>dispatcher</servlet-name>
   <url-pattern>/</url-pattern>
</servlet-mapping>

 

'/'로 매핑된 경우 .jsp로 끝나는 요청을 제외한 요청을 DispatcherServlet이 처리하게 된다. @EnableWebMvc 애노테이션 이 등록하는 HandlerMapping은 @Controller 애노테이션을 적용한 빈 객체여서 요청 경로만 대응가능하다. DefaultServletHandlerConfigurer는 DefaultServletHttpRequestHandler 와 SimpleUrlHandlerMapping 빈 객체들을 추가한다. DefaultServletHandlerConfigurer은 요청사항을 WAS의 디폴트 서블릿을 전달한다. SimpleUrlHandlerMapping을 이용하여 모든 경로를 DefaultServletHttpRequestHandler 를 이용해서 처리하도록 설정한다.

 

* LongestPrefix 법칙

 - 정보가 더 정확한(범위가 좁은) 작업부터 처리한다.