Spring/[인프런 김영한 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술]
[인프런 김영한 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술] 스프링 MVC - 구조 이해
h2boom
2024. 10. 4. 15:04
스프링 MVC - 구조 이해
스프링 MVC 전체 구조
- DispatcherServlet : 프론트 컨트롤러 패턴을 구현한 FrontController 역할을 하는 서블릿이다.
- 스프링 MVC에서의 핵심
- 스프링 부트에서 서블릿으로 자동 등록하면서 모든 경로("/")에 대해서 매핑한다.
- 자세한 경로가 우선 순위가 더 높다.
- 부모에서 service()가 시작되면 DispatcherServlet의 doDispatch()가 호출된다.
- 핸들러 조회, 핸들러 어댑터 조회, 핸들러 어댑터 실행, 핸들러 실행, ModelAndView 반환의 기능을 수행한다.
- 스프링 MVC 동작 순서
- 핸들러 조회 : 핸들러 매핑을 통해 요청 URL에 매핑된 핸들러(컨트롤러)를 조회한다.
- 핸들러 어댑터 조회 : 핸들러를 실행할 수 있는 핸들러 어댑터를 조회한다.
- 핸들러 어댑터 실행 : 핸들러 어댑터를 실행한다.
- 핸들러 실행 : 핸들러 어댑터가 실제 핸들러를 실행한다.
- ModelAndView 반환 : 핸들러 어댑터는 핸들러가 반환하는 정보를 ModelAndView로 변환해서 반환한다.
- viewResolver 호출 : 뷰 리졸버를 찾고 실행한다.
- View 반환 : 뷰 리졸버로 뷰의 논리 이름을 물리 이름으로 바꾸고 렌더링 역할을 하는 뷰 객체를 반환한다.
- 뷰 렌더링 : 뷰를 통해서 뷰를 렌더링한다.
핸들러 매핑과 핸들러 어댑터
- 스프링 부트가 자동 등록하는 핸들러 매핑과 핸들러 어댑터
- HandlerMapping 우선 순위 (실제로 더 많지만 중요한 것만 다룸)
- 0순위 RequestMappingHandlerMapping - 어노테이션 기반 컨트롤러인 @RequestMapping에서 사용
- 1순위 BeanNameUrlHandlerMapping - 스프링 빈 이름으로 핸들러를 찾는다.
=> URL을 보고 먼저 어노테이션 기반으로 찾고 없으면 스프링 빈 이름을 찾는다.
- HandlerAdapter 우선 순위
- 0순위 RequestMappingHandlerAdapter - 어노테이션 기반의 컨트롤러인 @RequestMapping에서 사용
- 1순위 HttpRequestHandlerAdapter - HttpRequestHandler 처리
- 2순위 SimpleControllerHandlerAdapter - Controller 인터페이스 (과거에 사용) 처리
- HandlerMapping 우선 순위 (실제로 더 많지만 중요한 것만 다룸)
- 개발자가 직접 핸들러 매핑과 핸들러 어댑터를 만들 일은 없다.
- 실무에서는 대부분 어노테이션 기반의 컨트롤러를 지원하는 매핑과 어댑터를 사용한다.
뷰 리졸버
- 스프링 부트에서 InternalResourceViewResolver라는 뷰 리졸버를 자동으로 등록
- application.yml / .properties에 등록한 spring.mvc.view.prefix / suffix 설정 정보를 기반으로 등록한다.
- 뷰 리졸버 우선 순위
- 0순위 BeanNameViewResolver - 빈 이름으로 뷰를 찾아서 반환한다.
- 1순위 InternalResourceViewResolver - JSP를 처리할 수 있는 뷰를 반환한다.
- 다른 뷰는 실제 뷰를 렌더링하지만 JSP의 경우는 forward()를 통해 해당 JSP로 이동해야 렌더링이 된다.
스프링 MVC
@Controller
public class SpringMemberFormControllerV1 {
@RequestMapping("/springmvc/v1/members/new-form")
public ModelAndView process() {
return new ModelAndView("new-form");
}
}
- @Controller
- 스프링이 자동으로 스프링 빈으로 등록한다.
(내부에 @Component 어노테이션이 있기에 컴포넌트 스캔 대상이 된다.) - 스프링 MVC에서 어노테이션 기반 컨트롤러로 인식한다.
- 스프링이 자동으로 스프링 빈으로 등록한다.
- @RequestMapping : 요청 정보를 매핑한다. 해당 URL이 호출되면 해당 어노테이션이 붙은 메소드가 호출된다.
- 어노테이션 기반으로 동작하기 때문에 메소드 이름은 임의로 지으면 된다.
- RequestMappingHandlerMapping은 스프링 빈 중에서 @RequestMapping이나 @Controller가 클래스 레벨에 붙은 경우에만 매핑 정보로 인식한다.
스프링 MVC - 컨트롤러 통합
@Controller
@RequestMapping("/springmvc/v2/members")
public class SpringMemberControllerV2 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@RequestMapping("/new-form")
public ModelAndView newForm() {
return new ModelAndView("new-form");
}
@RequestMapping("/save")
public ModelAndView save(HttpServletRequest request, HttpServletResponse response) {
String username = request.getParameter("username");
int age = Integer.parseInt(request.getParameter("age"));
Member member = new Member(username, age);
memberRepository.save(member);
ModelAndView mv = new ModelAndView("save-result");
mv.addObject("member", member);
return mv;
}
@RequestMapping
public ModelAndView members() {
List<Member> members = memberRepository.findAll();
ModelAndView mv = new ModelAndView("members");
mv.addObject("members", members);
return mv;
}
}
- @RequestMapping은 메소드 레벨에 사용할 수 있기 때문에 컨트롤러를 통합해서 사용할 수 있다.
- 각 메소드 매핑 URL의 중복은 클래스 레벨에 @RequestMapping(URL)로 공통 처리를 해줄 수 있으며 메소드 레벨과 조합이 된다.
스프링 MVC - 실용적인 방식
@Controller
@RequestMapping("/springmvc/v3/members")
public class SpringMemberControllerV3 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@RequestMapping(value = "/new-form", method = RequestMethod.GET)
//@GetMapping()
public String newForm() {
return "new-form";
}
@RequestMapping(value = "/save", method = RequestMethod.POST)
public String save(@RequestParam("username") String username,
@RequestParam("age") int age,
Model model) {
Member member = new Member(username, age);
memberRepository.save(member);
model.addAttribute("member", member);
return "save-result";
}
@RequestMapping(method = RequestMethod.GET)
//@PostMapping()
public String members(Model model) {
List<Member> members = memberRepository.findAll();
model.addAttribute("members", members);
return "members";
}
}
- 스프링 MVC에서 어노테이션 방식은 ModelAndView를 반환해도 되지만 String을 반환하는 방식도 있다.
- String을 반환하는 경우 뷰의 논리명을 문자열로 반환한다.
- @RequestParam : HTTP 요청 파라미터를 처리하는 어노테이션으로 HttpServletRequest의 getParameter()와 기능이 동일하다
- Model 파라미터를 받아서 렌더링에 필요한 데이터를 넘겨줄 수 있다.
- 기존 @RequestMapping 방식은 해당 URL이면 GET 이든 POST 이든지 상관 없이 무조건 호출하는 방식이였다.
- 속성에 method로 방식을 지정하면 해당 방식으로 요청이 올 때만 호출된다.
- Get 방식인 경우 @GetMapping, POST 방식의 경우 @PostMapping도 같은 기능을 수행한다.
- GET, POST, PUT, DELETE, PATCH 모두 어노테이션으로 제공한다.
출처 : [인프런 김영한 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술]
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard
스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 강의 | 김영한 - 인프런
김영한 | 웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습
www.inflearn.com