spring

[Spring MVC 1편] 스프링 MVC- 구조 이해

kimkim615 2024. 8. 9. 17:16

스프링 MVC 전체 구조

 

 

 

 

기존 코드와 SpringMVC를 비교해보면 구조가 똑같고 이름에 차이가 있다.

직접 만든 프레임워크  스프링 MVC
FrontController DispatcherServlet
handlerMappingMap HandlerMapping
MyHandlerAdapter HandlerAdapter
ModelView ModelAndView
viewResolver ViewResolver
MyView View

 

스프링에서는 viewResolver를 인터페이스로 만들어놨다

그리고 스프링MVC에서는 컨트롤러가 바로 DispatcherServlet이다.

DispatcherServlet도 HttpServlet을 상속받아서 사용하고 서블릿으로 동작한다.

 

스프링 부트는 DispatcherServlet을 서블릿으로 자동 등록하면서 모든 경로 (urlPatterns="/")에 대해 매핑한다

 

서블릿이 호출되면 HttpServlet이 제공하는 service()가 호출이 되는데

스프링 MVC는 DispatcherServlet의 부모 FrameworkServlet()에서 service()를 오버라이드 해두었다

최종적으로는 DispatcherServlet.doDispatch()가 호출된다

 

DispatcherServlet.doDispatch()

1. 핸들러 조회 : 핸들러 매핑을 통해 요청 URL에 매핑된 핸들러를 조회한다

 

2. 핸들러 어댑터 조회 : 핸들러를 처리할 수 있는 어댑터를 조회한다

 

3. 핸들러 어댑터 실행 -> 4. 핸들러 어댑터를 통한 핸들러 실행 -> 5. ModelAndView 반환  

 

6. 뷰 리졸버를 통해 뷰 찾기 -> 7. 뷰 반환

 

8. 뷰 렌더링

 

핸들러 매핑과 핸들러 어댑터

 

@Component로 스프링 이름이 /springmvc/old-controller로 등록되었다

스프링 빈의 이름을 URL 패턴이랑 맞춘거다

 

링크를 호출하면 http요청이 들어간다 그러면 핸들러 매핑에서 OldController를 찾아와야된다

컨트롤러가 호출되려면 1.핸들러 매핑 - 스프링 빈의 이름으로 핸들러를 찾을 수 있는 핸들러 매핑이 필요하다

2.핸들러 어댑터 - controller 인터페이스를 실행할 수 있는 핸들러 어댑터를 찾고 실행해야된다

 

스프링은 이미 필요한 핸들러 매핑과 핸들러 어댑터를 대부분 구현해놔서 개발자가 만드는 일은 거의 없다

 

뷰 리졸버

논리 뷰 이름으로 viewResolver가 호출이 될 때 스프링 부트가 자동으로 여러 뷰 리졸버를 등록해준다

 

1. 핸들러 어댑터 호출

핸들러 어댑터를 통해 new-form 이라는 논리뷰 이름 획득

 

2. ViewResolver 호출

new-form이라는 뷰 이름으로 viewResolver 순서대로 호출

이때 InternalResourceViewResolver가 호출됨

 

3. InternalResourceViewResolver

이 뷰 리졸버는 InternalResourceView를 반환

 

4. 뷰 - InternalResourceView

InternalResourceView는 JSP처럼 포워드 forward()를 호출해서 처리할 수 있는 경우에 사용한

 

5. view.render()

view.render()가 호출되고 InternalResourceView는 forward()를 사용해서 JSP를 실행한다

 

스프링 MVC - 시작하기

@RequestMapping

스프링이 어노테이션을 활용한 매우 유용하고 실용적인 컨트롤러를 만들었는데 그게 바로 RequestMapping이다

스프링에서는 핸들러매핑 RequestMappingHandlerMapping과 핸들러 어댑터 RequestMappingHandlerAdapter를 제공한다

 

hello/servlet/web/springmvc/v1/SpringMemberFormControllerV1.class

 

회원 등록 폼을 만들어볼 것이다

 

@Controller : 자동으로 스프링 빈으로 등록한다 -> @Component가 이 애노테이션 안에 들어있다.

그리고 스프링 MVC에서 애노테이션 기반 컨트롤러로 인식한다

@RequestMapping : 요청 정보를 매핑한다. 저 URL이 호출되면 이 메서드가 호출된다

메서드 이름 (process)는 아무거나 적어도 된다

ModelAndView : 모델, 뷰 정보를 담아서 반환하면 된다

 

hello/servlet/springmvc/v1/SpringMemberSaveControllerV1.class

 

 

스프링 MVC - 컨트롤러 통합

@RequestMapping을 보면 클래스 단위가 아닌, 메서드 단위에 선언되면서 적용된 것을 볼 수 있다.

그러니까 컨트롤러 클래스를 하나로 통합할 수 있다.

 

hello/servlet/web/springmvc/v2/SpringMemberControllerV2.class

위에서 각각 만들었던 파일들을 이 SpringMemberControllerV2에 다 복붙해서 하나의 컨트롤러로 통합할 수 있다

 

 

클래스 레벨에 @RequestMapping("/springmvc/v2/members")를 두면 메서드 레벨과 조합이 된다. 

그래서 코드 중복을 제거할 수 있다

 

스프링 MVC - 실용적인 방식

이제 ModelView를 개발자가 직접 생성해서 반환하지 않도록 개선할 것이다.

실무에서는 지금부터 설명하는 방식으로 주로 사용한다.

 

hello/servlet/web/springmvc/v3/SpringMemberControllerV3.class

 

1. new-form 반환하는 타입을 String으로 바꾼다

스프링에서는 유연하게 그냥 문자로 반환해도 view 이름으로 알고 프로세스가 진행이 된다

 

2. 파라미터를 직접 바꾸는 것으로 바꾼다

@RequestParam("username") String username,

@RequestParam("age") int age,

Model model

요청 파라미터 받고, 모델에 담고 뷰에 이름 반환해주면 끝난다

 

3. http 메서드를 넣어서 구분한다

@GetMapping @PostMapping