[Spring MVC] 기본 구조

    반응형

     

    이 글은 코드로 배우는 스프링 웹 프로젝트(남가람북스, 구멍가게 코딩단)을 읽고 공부한 내용을 바탕으로 정리한 글입니다.


     

    1. 프로젝트 실행 과정

     

    [Spring] Spring MVC Project 생성하기(IntelliJ)

    이 글은 더블에스 Devlog 블로그를 참고하여 정리한 내용을 바탕으로 작성한 글입니다. IntelliJ에서 Spring MVC Project 생성하기 - 더블에스 Devlog IntelliJ에서는 STS(Spring Tool Suite)처럼 Spring MVC Project를 생

    eunbin00.tistory.com

    기본적으로 프로젝트를 생성하고 정상적으로 실행되었다면 톰캣 서버 구동 시, 아래 이미지처럼 로그가 찍히는 것을 볼 수 있습니다. 이 로그를 하나씩 보면서 어떤 과정을 통해서 프로젝트가 실행되는지 알아봅시다.

    서버 구동시 찍히는 로그

    프로젝트 구동 시 관여하는 XML은 web.xml, applicationContext.xml, dispatcher-servlet.xml 파일입니다. 여기서 web.xml은 톰캣 구동과 관련된 설정파일이고, 나머지 두 파일은 스프링과 관련된 설정파일입니다.

     

    1. web.xml

    프로젝트 구동은 web.xml에서 시작합니다. web.xml의 상단에는 가장 먼저 구동되는 Context Listener가 등록되어 있습니다.

    web.xml

    • <context-param>에는 applicationContext.xml의 경로가 지정되어 있습니다.
    • <listener>에는 스프링 MVC의 ContextLoaderListener가 등록되어 있습니다. ContextLoaderListener는 해당 웹 어플리케이션 구동 시 같이 동작하므로 프로젝트를 실행하면 가장 먼저 로그를 찍습니다.
    INFO : org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization started
    INFO : org.springframework.web.context.support.XmlWebApplicationContext - Refreshing Root WebApplicationContext: startup date [Mon Jan 02 15:22:53 KST 2023]; root of context hierarchy

    2. applicationContext.xml

    applicationContext.xml이 처리되면 파일에 있는 Bean 설정이 동작합니다. applicationContext.xml에 정의된 객체(Bean)들은 스프링 context 안에 생성되고, 객체들 간의 의존성이 처리됩니다. 

    3. dispatcher-servlet.xml

    appllicationContext.xml이 처리된 후에는 스프링 MVC에서 사용하는 DispatcherServlet이라는 서블릿과 관련된 설정이 동작합니다. 위에서 보면 web.xml에 마찬가지로 서블릿 설정 파일인 dispatcher-servlet.xml의 경로를 설정해 주었습니다.

    org.springframework.web.servlet.DispatcherServlet 클래스는 스프링 MVC 구조에서 가장 핵심적인 역할을 하는 클래스입니다. 내부적으로 웹 관련 처리의 준비작업을 진행하는데 이때 사용하는 파일이 dispatcher-servlet.xml 입니다.

    INFO : org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 484 ms INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcher': initialization started INFO : org.springframework.web.context.support.XmlWebApplicationContext - Refreshing WebApplicationContext for namespace 'dispatcher-servlet': startup date [Mon Jan 02 15:22:53 KST 2023]; parent: Root WebApplicationContext INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/spring-config/dispatcher-servlet.xml] INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcher': initialization completed in 10 ms

    로그를 보면 위와 같은데, DispatcherServlet에서 XMLWebApplicatonContext를 이용해서 dispatcher-servlet.xml을 로딩하고 해석합니다. 이 과정에서 등록된 객체(Bean)들은 기존에 applicationContext.xml에서 정의된 객체(Bean)들과 연동되게 됩니다.

    2. 모델2와 스프링 MVC

    모델2 방식은 로직과 화면을 분리하는 스타일의 개발방식 입니다. 모델2 방식을 사용한 스프링 MVC의 기본 구조는 아래와 같이 표현할 수 있습니다.

    1. HTTP 요청: 사용자가 HTTP 요청을 합니다. 사용자의 Request는 Front-Controller인 DispatcherServlet을 통해서 처리합니다. 앞서 작성한 web.xml을 보면 모든 Request를 DispatcherServlet이 받도록 처리하고 있습니다.

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring-config/dispatcher-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    2. HandlerMapping: Request의 처리를 담당하는 컨트롤러를 찾기 위해 존재합니다. HandlerMapping 인터페이스를 구현한 여러 객체들 중 RequestMappingHandlerMapping은 개발자가 @RequestMapping 어노테이션을 적용한 것을 기준으로 판단합니다.

    3. HandlerAdapter: HandlerMapping이 적절한 Controller을 찾았다면 HandlerAdapter를 이용해서 Controller를 동작시킵니다.

    4. Controller: 개발자가 작성하는 실제 클래스입니다. 실제 Request를 처리하는 로직을 작성합니다. 이때, View에 전달해야 하는 데이터는 주로 Model이라는 객체에 담아서 전달합니다. Controller는 다양한 타입의 결과를 반환하는데, 이에 대한 처리는 ViewResolver를 이용합니다.

    예를 들어, 프로젝트 생성 포스팅에서 작성했던 HomeController를 보면, 다음과 같습니다.

    @Controller
    public class HomeController {
    
        @RequestMapping("/")
        public String home(Model model) {
    
            model.addAttribute("greeting", "hello world");
    
            return "home";
        }
    
    }

    model 객체에 속성을 추가하여 home를 return하고 있습니다.

    5. ViewResolver: Controller가 반환한 결과를 어떤 View를 통해 처리하는 것이 좋을지 해석한ㄴ 역할입니다. 가장 흔하게 사용하는 설정은 dispatcher-servlet.xml에 정의된 InternalResourceViewResolver입니다.

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    dispatcher-servlet.xml에 위 코드를 작성해놓았는데, 그럼 HomeController에서 리턴값이 home이었으니, prefix와 suffix가 붙어서 /WEB-INF/views/home.jsp가 View로 나타나는 것입니다.

    6. Http 응답: View는 실제로 응답 보내야 하는 데이터를 Jsp 등을 이용해서 생성하는 역할을 합니다. 만들어진 응답은 DispatcherServlet을 통해 전송됩니다.

     

    이렇게 모든 Requestrk DispatcherServlet을 통하도록 설계하는 것을 Front-Controller 패턴이라고 한는데, Front-Controller 패턴을 이용하면 모든 Request의 처리에 대한 분배가 정해진 방식대로만 동작하기 때문에 좀 더 엄격한 구조를 만들어 낼 수 있습니다.

    반응형

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

    [Spring MVC] 파일업로드 처리  (0) 2023.01.03
    [Spring MVC] Controller  (0) 2023.01.03
    [Spring] MyBatis와 스프링 연동 (+log4jdbc)  (0) 2023.01.02
    [Spring] JDBC(MySQL) 연결  (0) 2023.01.02
    [Spring] 의존성 주입(DI)  (1) 2022.12.30

    댓글