[Spring] ๐Ÿ“š Dispatcher Servlet ์ดํ•ดํ•˜๊ธฐ

ํ—Œ์น˜ยท2022๋…„ 8์›” 22์ผ
10

Spring

๋ชฉ๋ก ๋ณด๊ธฐ
5/13
post-thumbnail

0. intro

์Šคํ”„๋ง์„ ๊ณต๋ถ€ํ•ด๋‚˜๊ฐ€๋ฉด์„œ ์–ด๋…ธํ…Œ์ด์…˜์—” ์ต์ˆ™ํ–ˆ์ง€๋งŒ ๊ตฌ์ฒด์ ์ธ ์ž‘๋™ ๋ฐฉ์‹์— ๋Œ€ํ•ด์„œ๋Š” ์ž˜ ๋ชฐ๋ž๋‹ค.

์ด๋ฒˆ์— CS์Šคํ„ฐ๋””์—์„œ Dispatcher Servlet ์ฃผ์ œ๋ฅผ ๋ฐœํ‘œํ•˜๊ธฐ๋กœ ๊ฒฐ์ •๋˜์—ˆ๋‹ค. ๊ด€๋ จํ•ด์„œ ์ฐพ์•„๋ดค๋Š”๋ฐ ์ต์ˆ™ํ•œ ๋‚ด์šฉ๋“ค(์ŠคํŽ˜์…œ ๋นˆโ€ฆ)๋„ ์žˆ์—ˆ๊ณ  ๋ชฐ๋ž๊ฑฐ๋‚˜ ์ž˜๋ชป ์•Œ๊ณ ์žˆ๋˜ ๋ถ€๋ถ„(Filter์™€ Interceptor์˜ ์ž‘๋™ ์œ„์น˜)๋“ค๋„ ์žˆ์—ˆ๋‹ค.

1) ์„œ๋ธ”๋ฆฟ(Java Servlet)?

์ž๋ฐ” ์„œ๋ธ”๋ฆฟ(Java Servlet)์€ย ์ž๋ฐ”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›นํŽ˜์ด์ง€๋ฅผ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ์„œ๋ฒ„์ธก ํ”„๋กœ๊ทธ๋žจ ํ˜น์€ ๊ทธ ์‚ฌ์–‘์„ ๋งํ•˜๋ฉฐ, ํ”ํžˆ "์„œ๋ธ”๋ฆฟ"์ด๋ผ ๋ถˆ๋ฆฐ๋‹ค. ์ž๋ฐ” ์„œ๋ธ”๋ฆฟ์€ ์›น ์„œ๋ฒ„์˜ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ์ž๋ฐ” ํด๋ž˜์Šค์˜ ์ผ์ข…์ด๋‹ค.
(โ€ฆ)
์ž๋ฐ” ์„œ๋ธ”๋ฆฟ์€ย `์ž๋ฐ” EEย ์‚ฌ์–‘์˜ ์ผ๋ถ€๋ถ„`์œผ๋กœ, ์ฃผ๋กœ ์ด ๊ธฐ๋Šฅ์„ ์ด์šฉํ•˜์—ฌ ์‡ผํ•‘๋ชฐ์ด๋‚˜ ์˜จ๋ผ์ธ ๋ฑ…ํ‚น ๋“ฑ์˜ ๋‹ค์–‘ํ•œ ์›น ์‹œ์Šคํ…œ์ด ๊ตฌํ˜„๋˜๊ณ  ์žˆ๋‹ค.
https://ko.wikipedia.org/wiki/์ž๋ฐ”_์„œ๋ธ”๋ฆฟ

์ฆ‰, ์„œ๋ธ”๋ฆฟ(Servlet)์€ ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์›น ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ธฐ์ˆ ์ด๋‹ค.

2) J2EE(Java EE)?

์ž๋ฐ” ๊ธฐ์ˆ ๋กœ ์–ดํ”Œ์„ ๋งŒ๋“ค ๋•Œ ํ•„์š”ํ•œ ์ŠคํŽ™(๊ตฌ์„ฑ์š”์†Œ, api, ๋Ÿฐํƒ€์ž„ ์ปจํ…Œ์ด๋„ˆ, ์„œ๋น„์Šค ๋“ฑ์— ๋Œ€ํ•œ ํ‘œ์ค€ ์‚ฌ์–‘)๋“ค์˜ ์ง‘ํ•ฉ์ด๋‹ค.
์ด์ „์—๋Š”ย J2EE๋ผ ๋ถˆ๋ฆฌ์—ˆ์œผ๋‚˜ ๋ฒ„์ „ 5.0 ์ดํ›„๋กœย Java EE๋กœ ๊ฐœ์นญ๋˜์—ˆ๋‹ค.
https://ko.wikipedia.org/wiki/์ž์นด๋ฅดํƒ€_EE

JSP(Java Server Page), Java Servlet, EJB(Enterprise JavaBeans) ๋“ฑ์˜ ๊ตฌ์„ฑ์š”์†Œ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค. ๊ฐœ๋ฐœ์ž๋“ค์€ ์ด๋Ÿฐ ๊ตฌ์„ฑ์š”์†Œ๋“ค๋กœ ๋Œ€๊ทœ๋ชจ ๋ถ„์‚ฐ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ๊ตฌ์ถ•ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ์ด๋Ÿฐ Java EE ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ JAR ํŒŒ์ผ๋กœ ๋ณ€ํ™˜ํ•ด ์ธ์Šคํ„ด์Šค๋กœ ๋ฐฐํฌํ•˜๊ฒŒ ๋œ๋‹ค~

1. ๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ(Dispatcher Servlet)?

0) Servlet์˜ ์ผ์ข…์ด๋‹ค!

public class DispatcherServlet extends FrameworkServlet {
}

public abstract class FrameworkServlet extends HttpServletBean {
}

public abstract class HttpServletBean extends HttpServlet {
}

๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ๋„ย Servlet์ด๋‹ค.

Dispatcher์˜ ๋œป์€ ๊ธ‰ํŒŒ์ž๋ผ๋Š” ์˜๋ฏธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ๋‹จ์–ด ์˜๋ฏธ ๊ทธ๋Œ€๋กœ ๊ฐ€์žฅ ๋จผ์ € ์š”์ฒญ์„ ๋จผ์ € ๋ฐ›๊ณ , ์ ์ ˆํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ํ•จ์ˆ˜, ์ฆ‰ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ฐพ์•„์„œ ์ •ํ•ด์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ์€ HttpServlet์„ ์ƒ์†ํ•œ๋‹ค.
(DispatcherServlet -> FrameworkServlet -> HttpServletBean -> HttpServlet ์ƒ์† ๊ตฌ์กฐ)

1) ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ(Front Controller) ํŒจํ„ด์ด๋‹ค!

๊ณผ๊ฑฐ์—๋Š” ๋ชจ๋“  ์„œ๋ธ”๋ฆฟ์„ URL ๋งคํ•‘์„ ์œ„ํ•ด web.xml์— ๋“ฑ๋กํ•ด์•ผ ํ–ˆ์ง€๋งŒ, ์ด์   ๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ์ด ์žˆ๋‹ค!

๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ์€ ์Šคํ”„๋ง MVC์˜ ์ค‘์•™ ์„œ๋ธ”๋ฆฟ์ด๋ฉฐ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์œผ๋กœ ์˜ค๋Š” ๋ชจ๋“  ์š”์ฒญ์„ ํ•ธ๋“ค๋งํ•˜๊ณ  ๊ณตํ†ต์ž‘์—…์„ ์ฒ˜๋ฆฌํ•ด์ค€๋‹ค.

์‹ค์ œ ์ž‘์—…(๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง, ์˜ˆ์™ธ์ฒ˜๋ฆฌ ๋“ฑ)์€ ์œ„์ž„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ†ตํ•ด ์ˆ˜ํ–‰๋œ๋‹ค.

๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ์„ ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ ๋ผ๊ณ ๋„ ๋ถ€๋ฅธ๋‹ค. ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ๋Š” ์„œ๋ธ”๋ฆฟ ์ปจํ…Œ์ด๋„ˆ ๋งจ ์•ž์—์„œ ๋ชจ๋“  ์š”์ฒญ์„ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•ด์ฃผ๋Š” ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

์ด๋Ÿฌํ•œ ํŒจํ„ด์„ ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ(Front Controller) ํŒจํ„ด์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.
๋ณด๋‹ค ์ž์„ธํ•œ ์„ค๋ช…

2) ์ •์ ์ž์›๊ณผ ๋™์  ์ž์›์„ ๋ถ„ํ•  ์ฒ˜๋ฆฌํ•œ๋‹ค!

๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ์„ ํ†ตํ•ด ์–ป์„ ์ˆ˜ ์žˆ๋Š” ์žฅ์ ์ด ๋˜ ์žˆ๋‹ค. ์ •์ ์ž์›๊ณผ ๋™์  ์ž์›์„ ๋”ฐ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค. (์„œ๋ธ”๋ฆฟ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค)

๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ์—์„œ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋จผ์ € ์ฐพ๊ณ , ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์—†์„๋• 2์ฐจ๋กœ ์„ค์ •๋œ ์ •์  ์ž์›์„ ํƒ์ƒ‰ํ•œ๋‹ค.

์ด๋ฅผ ํ†ตํ•ด ํšจ์œจ์ ์ธ ๋ฆฌ์†Œ์Šค ๊ด€๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•ด์ง„๋‹ค!

2. ์„ค์ • ๋ฐฉ๋ฒ•

1) ๋“ฑ๋ก ๋ฐ ์ดˆ๊ธฐํ™”

๋ชจ๋“  ์„œ๋ธ”๋ฆฟ์ด ๊ทธ๋ ‡๋“ฏ, ๋””์ŠคํŒจ์ณ ์„œ๋ธ”๋ฆฟ๋„ ์ž๋ฐ”๋‚˜ web.xml์„ ํ†ตํ•ด ๋“ฑ๋ก ๋ฐ ์ดˆ๊ธฐํ™” ๋˜์–ด์•ผ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.

ํ†ฐ์บฃ ๋“ฑ ์„œ๋ธ”๋ฆฟ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ํ†ตํ•ด ๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ด๋‹ค. ์•„๋ž˜ ๋ฐฉ๋ฒ•์œผ๋กœ ์›์‹œ์ ์ธ ์„ค์ •๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

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/*");
    }
}

Java

<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>

web.xml

3. ๊ตฌ์กฐ

0) Servlet Container

์„œ๋ธ”๋ฆฟ์€ ์Šค์Šค๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋ณดํ†ต ์„œ๋ธ”๋ฆฟ์„ ๊ด€๋ฆฌํ•  ์„œ๋ธ”๋ฆฟ ์ปจํ…Œ์ด๋„ˆ(ํ†ฐ์บฃ ๋“ฑ)๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

์„œ๋ธ”๋ฆฟ ์ปจํ…Œ์ด๋„ˆ๋Š” ์‹ฑ๊ธ€ํ†ค์ธ ์„œ๋ธ”๋ฆฟ ๊ฐ์ฒด์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค. ๋˜ํ•œ ์›น์„œ๋ฒ„์™€ ์†Œ์ผ“์œผ๋กœ ํ†ต์‹ ํ•˜๋ฉฐ, ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ๋ฐ›๊ณ  ์‘๋‹ต์„ ๋ณด๋‚ด์ค€๋‹ค. ๋ฉ€ํ‹ฐ์“ฐ๋ ˆ๋“œ ์ฒ˜๋ฆฌ๋„ ์ง€์›ํ•œ๋‹ค.

1) WebApplicationContext

๋””์ŠคํŒจ์ณ ์„œ๋ธ”๋ฆฟ์€

  1. Servlet WebApplicationContext ์„ ์ƒ์„ฑํ•˜๊ณ 
  2. ๋ณดํ†ต Root WebApplicationContext ์„ ์ƒ์„ฑํ•œ๋‹ค.

์„œ๋ธ”๋ฆฟ WebApplicationContext ์•ˆ์—๋Š” ServletContext์™€ ์—ฐ๊ด€๋œ Servlet ๋งํฌ๋“ค์ด ์žˆ๋‹ค.

Controller, ViewResolver, HandlerMapping ๋“ฑ์ด ์ด ์•ˆ์— ์žˆ๋‹ค. RequestContextUtils ์˜ ์ •์  ๋ฉ”์†Œ๋“œ๋“ค์„ ์‚ฌ์šฉํ•ด ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด WebApplicationContext๋ฅผ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค.

Root WebApplicationContext ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ, infra bean์ด ์ด ์•ˆ์— ๋“ค์–ด๊ฐ„๋‹ค. Repository, Service ๋นˆ ๋“ฑ์ด ์ธํ”„๋ผ ๋นˆ์ด๋‹ค.

WebApplicationContext ์„ค์ •์€ java๋‚˜ web.xml ์„ ํ†ตํ•ด ํ•  ์ˆ˜ ์žˆ๋‹ค.

public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] { RootConfig.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] { App1Config.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/app1/*" };
    }
}

Java

<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>

web.xml

2) ์ŠคํŽ˜์…œ ๋นˆ(Special Bean)

์•„๊นŒ ๋งํ–ˆ๋“ฏ, ๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ์€ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์œ„์ž„ ์ปดํฌ๋„ŒํŠธ์— ์‹ค์ œ ์ž‘์—…์„ ๋งก๊ธด๋‹ค. ์ด๋Ÿฐ ์œ„์ž„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ŠคํŽ˜์…œ ๋นˆ(Special Bean)์ด๋ผ๊ณ ๋„ ๋ถ€๋ฅธ๋‹ค.

์ŠคํŽ˜์…œ ๋นˆ์€ ํ”„๋ ˆ์ž„์›Œํฌ ๊ณ„์•ฝ์„ ๊ตฌํ˜„ํ•˜๋Š” ์Šคํ”„๋ง ๊ด€๋ฆฌ ๊ฐ์ฒด ์ธ์Šคํ„ด์Šค๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด ์Šคํ”„๋ง์—์„œ ์ œ๊ณตํ•˜๋Š” ์ฃผ์š” ๋นˆ๋“ค์ด๋‹ค. ์ŠคํŽ˜์…œ ๋นˆ๋“ค๋งˆ๋‹ค ์ œ๊ณต๋˜๋Š” ์ผ๋ฐ˜์ ์ธ ์„ค์ •๋“ค์ด ์žˆ์ง€๋งŒ ์‚ฌ์šฉ์ž(์ฆ‰, ํ”„๋กœ๊ทธ๋ž˜๋จธ)๊ฐ€ ์ž„์˜๋กœ ์žฌ์ •์˜ํ•˜๊ฑฐ๋‚˜ ๊ต์ฒด๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ํ•œ๋‹ค.

๋‹ค์Œ์€ ๋””์ŠคํŒจ์ณ ์„œ๋ธ”๋ฆฟ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ŠคํŽ˜์…œ ๋นˆ๋“ค์ด๋‹ค.

  1. handlerMapping : ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ฐพ๋Š”๋‹ค
  2. handlerAdapter : ์š”์ฒญ์„ ์ปจํŠธ๋กค๋Ÿฌ๋กœ ์ „๋‹ฌํ•œ๋‹ค
  3. handlerExceptionResolver : ์š”์ฒญ์— ๋Œ€ํ•œ ์˜ˆ์™ธ ๋ฐœ์ƒ(ํ•ธ๋“ค๋Ÿฌ ๋งคํ•‘ ๋„์ค‘, ์ปจํŠธ๋กค๋Ÿฌ ์‹คํ–‰ ๋„์ค‘) ์‹œ ์ฒ˜๋ฆฌํ•ด์ค€๋‹ค
  4. viewResolver : ๋ฆฌํ„ด๊ฐ’์— ๋Œ€ํ•œ ๋ทฐ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. string์œผ๋กœ ๋ทฐ ์ด๋ฆ„์„ ์ „๋‹ฌ๋ฐ›์•˜์„ ๋•Œ ์ด๋ฅผ modelAndView ๋“ฑ์˜ ๊ฐ์ฒด๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  5. LocaleResolver : Locale์„ ๊ฒฐ์ •ํ•œ๋‹ค. ์ฐธ๊ณ ๋กœ Locale์€ ์œ ์ €์˜ ์–ธ์–ด,์ง€์—ญ,์ถœ๋ ฅํ˜•์‹ ๋“ฑ์„ ์ •์˜ํ•˜๋Š” ๋ฌธ์ž์—ด์ด๋‹ค.
  6. MultipartResolver : ๋ฉ€ํ‹ฐํŒŒํŠธ ํŒŒ์ผ ์—…๋กœ๋“œ๋ฅผ ์ฒ˜๋ฆฌํ•ด์ค€๋‹ค. ์ฐธ๊ณ ๋กœ ๋ฉ€ํ‹ฐํŒŒํŠธ๋Š” HTTP ์‘๋‹ต์˜ ๋ฐ”๋””๋ฅผ ์—ฌ๋Ÿฌ ํŒŒํŠธ๋กœ ๋‚˜๋ˆ ์„œ ๋ณด๋‚ด์ค„ ๋•Œ์˜ ํŒŒ์ผ ํ˜•์‹์„ ์˜๋ฏธํ•œ๋‹ค.

4. ์ž‘๋™ ๋ฐฉ์‹

๊ฐ„๋žต ๋ฒ„์ „

์ƒ์„ธ ๋ฒ„์ „

๋””์ŠคํŒจ์ณ ์„œ๋ธ”๋ฆฟ์€ ๋‹ค์Œ ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•œ๋‹ค.

  1. ํด๋ผ์ด์–ธํŠธ(์•„๋งˆ ํ”„๋ก ํŠธ ์„œ๋ฒ„) ์š”์ฒญ์„ ๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ์ด ๋ฐ›๋Š”๋‹ค.
    1. ์ด๋•Œ filter๋ฅผ ๊ฒฝ์œ ํ•  ์ˆ˜ ์žˆ๋‹คใ…‹

      filter๋„ ๋‚˜์ค‘์— ์ •๋ฆฌํ•ด๋‚˜๊ฐˆ ์˜ˆ์ •โ€ฆ

  2. ์š”์ฒญ ์ •๋ณด๋ฅผ ๋ณด๊ณ  Servlet WebApplicationContext ์•ˆ์—์„œ HandlerMapping์„ ํ†ตํ•ด ์š”์ฒญ์„ ์œ„์ž„ํ•  ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๊ฒ€์ƒ‰ํ•ด ์ฐพ๋Š”๋‹ค.
  3. ์ฐพ์€ ์ปจํŠธ๋กค๋Ÿฌ๋กœ ์š”์ฒญ์„ ์œ„์ž„ํ•  HandlerAdapter๋ฅผ ์ฐพ๋Š”๋‹ค.
    1. ์ด๋•Œ Interceptor preHandle์ด ์‹คํ–‰๋œ๋‹ค.
  4. HandlerAdapter๊ฐ€ ์ปจํŠธ๋กค๋Ÿฌ๋กœ ์š”์ฒญ(HttpRequest)์„ ์œ„์ž„ํ•œ๋‹ค
    1. Argument Resolver๊ฐ€ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•ด ์ปจํŠธ๋กค๋Ÿฌ๋กœ ๋ณด๋‚ธ๋‹ค.
  5. ์ปจํŠธ๋กค๋Ÿฌ๋Š” Root WebApplicationContext ์† Service, Repositoryโ€ฆ ๋“ฑ์„ ํ˜ธ์ถœํ•ด๊ฐ€๋ฉฐ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•œ๋‹ค.
  6. ์ปจํŠธ๋กค๋Ÿฌ ๋ฉ”์†Œ๋“œ์—์„œ ์ตœ์ข…์ ์ธ ๋ฐ˜ํ™˜๊ฐ’(Response Entity)์ด ๋ฆฌํ„ด๋œ๋‹ค.
    1. ๋ฆฌํ„ด ๊ฐ’์— ๋Œ€ํ•ด Interceptor postHandle์ด ์‹คํ–‰๋œ๋‹ค.
  7. ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ ๋ฆฌํ„ด๊ฐ’์„ ViewResolver์— ์ „๋‹ฌํ•œ๋‹ค.
  8. ViewResolver๊ฐ€ View๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ณ  ์ฐพ์€ View์— ์‘๋‹ต์„ ์ „๋‹ฌํ•œ๋‹ค.
    1. ์ดํ›„ Interceptor afterCompletion์ด ์‹คํ–‰๋œ๋‹ค.
  9. ๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ์—์„œ View๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ์‘๋‹ต์„ ํด๋ผ์ด์–ธํŠธ(ํ”„๋ก ํŠธ ์„œ๋ฒ„)๋กœ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค!

๊ฐ ๊ณผ์ •๋“ค์„ ์ฝ”๋“œ์™€ ํ•จ๊ป˜ ๋” ์ž์„ธํžˆ ์•Œ๊ณ ์‹ถ๋‹ค๋ฉด tecoble ๊ธ€์„ ์ฐธ๊ณ ํ•˜์ž.


ํ•ด๋‹น ๊ฐœ๋…์„ ๊ณต๋ถ€ํ•œ ํ›„, ์šฐ์•„ํ•œํ…Œํฌ์ฝ”์Šค ๋ ˆ๋ฒจ4 ๋ฏธ์…˜์—์„œ ์ง์ ‘ ๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ์„ ๊ตฌํ˜„ํ•ด๋ณด์•˜๋‹ค.
1๋‹จ๊ณ„ : ๊ธฐ๋ณธ ์„œ๋ธ”๋ฆฟ ๊ณจ๊ฒฉ ๊ตฌํ˜„
2๋‹จ๊ณ„ : ๋ ˆ๊ฑฐ์‹œ ์ปจํŠธ๋กค๋Ÿฌ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜
3๋‹จ๊ณ„ : ์–ด๋…ธํ…Œ์ด์…˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ณ€๊ฒฝ, ๋ทฐ ์ฒ˜๋ฆฌ
์‹ค์ œ ๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ๊ณผ ์ •ํ™•ํžˆ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค๊ณ  ๋ณผ ์ˆ˜๋Š” ์—†๊ฒ ์ง€๋งŒ, ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ฅผ ์ตœ๋Œ€ํ•œ ๋ฐ˜์˜ํ•˜๋ ค ๋…ธ๋ ฅํ–ˆ๋‹ค.


5. ์ฐธ๊ณ ์ž๋ฃŒ

1) ๊ณต์‹ ๋ฌธ์„œ/Wiki

15.2 The DispatcherServlet
What is Dispatcher Servlet in Spring? - GeeksforGeeks
Web on Servlet Stack
์ž๋ฐ” ์„œ๋ธ”๋ฆฟ - ์œ„ํ‚ค๋ฐฑ๊ณผ, ์šฐ๋ฆฌ ๋ชจ๋‘์˜ ๋ฐฑ๊ณผ์‚ฌ์ „

2) ์•„ํ‹ฐํด

Tecoble

Servlet ๊ณผ ServletContainer
DispatcherServlet - Part 1
DispatcherServlet - Part 2
Spring ArgumentResolver์™€ Interceptor

๋ธ”๋กœ๊ทธ

Front Controller Design Pattern - GeeksforGeeks
[Spring] Dispatcher-Servlet(๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ)์ด๋ž€? ๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ์˜ ๊ฐœ๋…๊ณผ ๋™์ž‘ ๊ณผ์ •
Spring์—์„œ Handler Interceptor ๊ฐœ๋… ๋ฐ ๊ตฌํ˜„ํ•ด๋ณด๊ธฐ
Spring MVC - DispatcherServlet ๋™์ž‘ ์›๋ฆฌ

6. ์งˆ๋ฌธ

1. Spring Web MVC์˜ Dispatcher Servlet์˜ ๋™์ž‘ ์›๋ฆฌ์— ๋Œ€ํ•ด์„œ ๊ฐ„๋‹จํžˆ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”.

์šฐ์„  ๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ์€ ์„œ๋ธ”๋ฆฟ ์ปจํ…Œ์ด๋„ˆ(ํ†ฐ์บฃ ๋“ฑ)์„ ํ†ตํ•ด ์ƒ๋ช…์ฃผ๊ธฐ๊ฐ€ ๊ด€๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ, ์‹ฑ๊ธ€ํ†ค ๋นˆ์ธ ๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ์€ ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ๋กœ, ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ๋“ค์„ ๋ฐ›์Šต๋‹ˆ๋‹ค.

์ดํ›„ ํ•ธ๋“ค๋Ÿฌ ๋งคํ•‘์„ ํ†ตํ•ด ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ปจํŠธ๋กค๋Ÿฌ(ํ•ธ๋“ค๋Ÿฌ)๋ฅผ ์ฐพ๊ณ , ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ๋ฅผ ํ†ตํ•ด ์›น์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ปจํ…์ŠคํŠธ ์†์—์„œ ๊ฒ€์ƒ‰๋œ ์ปจํŠธ๋กค๋Ÿฌ๋กœ ์š”์ฒญ์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
์ดํ›„ ์›น์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ปจํ…์ŠคํŠธ๋ฅผ ํ†ตํ•ด ์„œ๋น„์Šค, DB ๋นˆ๋“ค์ด ํ˜ธ์ถœ๋˜๋ฉฐ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. ์ปจํŠธ๋กค๋Ÿฌ์˜ ๋ฆฌํ„ด๊ฐ’ ์—ญ์‹œ ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ๋ฅผ ํ†ตํ•ด ๋ทฐ๋ฆฌ์กธ๋ฒ„์— ์ „๋‹ฌ๋˜๊ณ , ์•ˆ์—์„œ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐ’์— ๋Œ€ํ•œ ModelAndView ๋“ฑ์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ๊ฐ์ฒด๋Š” ๋ทฐ๋กœ ์ „๋‹ฌ๋˜๊ณ ์š”.

๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ์€ ์ตœ์ข…์ ์œผ๋กœ ๋ทฐ์—์„œ ์ „๋‹ฌ๋ฐ›์€ ๋ฆฌํ„ด๊ฐ’์„ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์‘๋‹ตํ•ด์ค๋‹ˆ๋‹ค.
์ด๋ ‡๋“ฏ ๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ์€ ์š”์ฒญ/์‘๋‹ต์— ๋Œ€ํ•œ ์ „์ฒ˜๋ฆฌ ๋ฐ, ์ปจํŠธ๋กค๋Ÿฌ ๋งคํ•‘ ๋“ฑ ๊ณตํ†ต ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๊ฐœ๋ฐœ์ž๋Š” ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ์ง‘์ค‘ํ•œ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

2. ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ ํŒจํ„ด์ด๋ž€ ๋ฌด์—‡์ธ๊ฐ€์š”?

ํด๋ผ์ด์–ธํŠธ์˜ ๋‹ค์–‘ํ•œ ์š”์ฒญ๋งˆ๋‹ค ์„œ๋ธ”๋ฆฟ์„ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•˜๋ฉด ๊ฐœ๋ฐœ๊ณผ ์œ ์ง€๋ณด์ˆ˜์˜ ํšจ์œจ์ด ๋–จ์–ด์งˆ ์ˆ˜ ๋ฐ–์— ์—†์Šต๋‹ˆ๋‹ค.

ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ ํŒจํ„ด์„ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ๊ฐ ์š”์ฒญ์„ ์ ์ ˆํ•œ ๊ณณ์œผ๋กœ ์œ„์ž„ํ•ด์คŒ์œผ๋กœ์จ ๊ฐœ๋ฐœ๊ณผ ์œ ์ง€๋ณด์ˆ˜์˜ ํšจ์œจ์„ฑ์ด ์ฆ๊ฐ€ํ•˜๊ณ  ๋ชจ๋“  ์š”์ฒญ์— ๋Œ€ํ•ด ๊ณตํ†ต ๊ธฐ๋Šฅ์„ ํ•œ ๊ณณ์—์„œ ์บก์Šํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Spring์—์„œ๋Š” DispatcherServlet์ด ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ ํŒจํ„ด์„ ์‚ฌ์šฉํ•œ ์˜ˆ์ž…๋‹ˆ๋‹ค. DispatcherServlet์ด Bean์œผ๋กœ ๋“ฑ๋ก๋˜์–ด package๋ฅผ scanํ•˜๊ณ  @Controller, @RestController ์• ๋…ธํ…Œ์ด์…˜์„ ํ™•์ธํ•˜์—ฌ ์–ด๋– ํ•œ ์š”์ฒญ์ด ๋“ค์–ด์™”์„ ๋•Œ ์ ์ ˆํ•œ Handler Method์— ์œ„์ž„ํ•ด์ค๋‹ˆ๋‹ค.

profile
๐ŸŒฑ ํ•จ๊ป˜ ์ž๋ผ๋Š” ์ค‘์ž…๋‹ˆ๋‹ค ๐Ÿš€ rerub0831@gmail.com

2๊ฐœ์˜ ๋Œ“๊ธ€

comment-user-thumbnail
2023๋…„ 2์›” 21์ผ

DispatcherServlet ๊ตฌ๊ธ€๋งํ•˜๋ฉด์„œ ๋ณธ ๊ธ€์ค‘์— ๊ฐ€์žฅ ํŽธํ•˜๋ฉด์„œ๋„ ์•Œ์ฐจ๊ฒŒ ์ •๋ณด๋ฅผ ์–ป์€ ๊ธ€ ๊ฐ™๋„ค์šฉ ์ž˜ ๋ณด๊ณ  ๊ฐ‘๋‹ˆ๋‹ค~

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ
comment-user-thumbnail
2023๋…„ 12์›” 6์ผ

์„œ๋ธ”๋ฆฟ ๊ด€๋ จํ•ด์„œ ๋งŽ์€ ์ฐธ๊ณ ๊ฐ€ ๋์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค~

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ