Spring/Spring MVC

[Spring MVC] 1-1. DispatcherServlet: Context Hierarchy

noahkim_ 2023. 10. 16. 00:53

1. Front Controller

  • 한 곳에서 요청을 받아서 적절한 컴포넌트에 라우팅하는 설계 패턴입니다.
  • Spring MVC는 프론트 컨트롤러 패턴으로 설계되었습니다.

 

DispatcherServlet

  • Spring MVC에서 프론트 컨트롤러 역할을 담당합니다. 
  • Java/XML 방식으로 설정 할 수 있습니다.

 

예제) XML

더보기

1. web.xml (webapp/WEB-INF/web.xml)

<web-app>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/app-context.xml</param-value>
    </context-param>

    <servlet>
        <servlet-name>app</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value></param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>app</servlet-name>
        <url-pattern>/app/*</url-pattern>
    </servlet-mapping>
</web-app>
설정 요소 설명
ContextLoaderListener Spring의 WebApplicationContext를 초기화하는 역할
웹 애플리케이션의 생명주기와 함께 실행
<context-param>
웹 애플리케이션 전역에서 사용되는 초기화 파라미터를 정의할 때 사용합니다.
- contextConfigLocation
ContextLoaderListener가 로드할 애플리케이션의 context 설정 파일 경로
예: /WEB-INF/spring/root-context.xml (전역적으로 사용되는 컴포넌트: Service, Repository)
예: /WEB-INF/spring/servlet-context.xml (애플리케이션에서 사용되는 컴포넌트: Controller)

 

예제) Java

더보기
public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) {
        // Load Spring web application configuration
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(AppConfig.class);

        // Create and register the DispatcherServlet
        DispatcherServlet servlet = new DispatcherServlet(context);
        ServletRegistration.Dynamic registration = servletContext.addServlet("app", servlet);
        registration.setLoadOnStartup(1);
        registration.addMapping("/app/*");
    }
}

WebApplicationInitializer

  • Servlet 3.0+ 환경에서 자동으로 감지되는 인터페이스
  • Tomcat이 애플리케이션을 시작할 때 onStartup()이 호출됨

 

ServletContext

  • 전체 웹 애플리케이션의 전역 공유 공간

 

2. Context Hierarchy

WebApplicationContext

항목 설명
정의
ApplicationContext의 확장 버전
웹 애플리케이션에 특화된 Spring 컨텍스트
연결 대상
ServletContext와 연결되어 있음 (웹 환경의 전역 저장소와 연결됨)
주요 역할
DispatcherServlet에게 구성 정보와 Bean들을 제공함
DispatcherServlet과의 관계
DispatcherServlet은 이 컨텍스트를 통해 Controller, Service 등의 Bean을 조회함
일반 구조
대부분의 웹 애플리케이션은 하나의 WebApplicationContext만 사용함
보유 기능
애플리케이션 전반에 걸친 공통 설정 및 Bean을 포함하고 있음

 

Context Hierarchy

  • 웹 애플리케이션의 복잡성에 따라 컨텍스트 계층 구조를 사용할 수 있습니다.
  • 복잡한 애플리케이션에서는 여러 개의 DispatcherServlet 인스턴스를 가질 수 있습니다.
  • 각 인스턴스는 WebApplicationContext를 가질 수 있으며, "Root" WebApplicationContext를 상속받습니다.
항목 Root WebApplicationContext
자식 WebApplicationContext
(DispatcherServlet 전용)
정의 애플리케이션 전체에서 공유되는 전역 Spring 컨텍스트
DispatcherServlet마다 개별적으로 가지는 전용 컨텍스트
인프라 관련 공통 빈
- 데이터소스, DAO, 서비스, 트랜잭션 설정 등
웹 계층 관련 빈
- 컨트롤러, 핸들러 매핑, 뷰 리졸버 등
설정 위치 <context-param>
(web.xml or WebApplicationInitializer)
setContextConfigLocation()
(DispatcherServlet 등록 시)
상속 관계 최상위 컨텍스트
RootContext로부터 상속받음
빈 재정의 가능
역할 범위 전체 애플리케이션 전역 범위
각 서블릿에 특화된 구성 및 기능 제공 (예: API, Admin 등)

 

예제) Root + Child

더보기
<web-app>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/root-context.xml</param-value>
    </context-param>

    <servlet>
        <servlet-name>app1</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/app1-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>app1</servlet-name>
        <url-pattern>/app1/*</url-pattern>
    </servlet-mapping>
</web-app>
public class MyWebAppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) {

        // 1. Root WebApplicationContext (공통 설정: 서비스, DAO 등)
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(RootConfig.class); // → /WEB-INF/root-context.xml에 해당

        // ContextLoaderListener로 RootContext 등록
        servletContext.addListener(new ContextLoaderListener(rootContext));

        // 2. Servlet WebApplicationContext (웹 계층 설정: 컨트롤러, 뷰 등)
        AnnotationConfigWebApplicationContext servletContextApp1 = new AnnotationConfigWebApplicationContext();
        servletContextApp1.register(App1ServletConfig.class); // → /WEB-INF/app1-context.xml에 해당

        // DispatcherServlet 생성 및 등록
        DispatcherServlet dispatcherServlet = new DispatcherServlet(servletContextApp1);
        ServletRegistration.Dynamic app1Servlet = servletContext.addServlet("app1", dispatcherServlet);
        app1Servlet.setLoadOnStartup(1);
        app1Servlet.addMapping("/app1/*");
    }
}

 

 

 

출처