저번에 Spring mvc 중에 DispatcherServlet에 대해서 알아봤다. 물론 저 설명은 핵심만 살펴본 내용이라 딱 와닿지 않을 수 있다. 인터페이스의 역할을 알아봤으니 각자가 구현클래스에 대해서 살펴보고 클래스가 어떤 역할을 하는 지 살펴보면 좋을 듯하다. Spring 문서에도 아주 잘 나와 있으니 참고하면 되겠다.

이번시간에 알아볼 내용은 Spring mvc의 설정과 spring boot의 설정도 같이 볼 예정이다.

우리는 예전에 Spring mvc로 개발할 때에는 web.xml을 사용해서 DispatcherServlet을 servlet으로 등록을 했다. 아주 예전에 servlet으로 개발할 때는 xml에 각각의 servlet을 등록하고 HttpServlet 상속받아 구현하였다. 아주 옛날이야기라 필자도 이렇게 개발한적은 학교 때 말고 없었던거 같다. 이제는 그럴필요 없이 DispatcherServlet만 servlet으로 등록하면 spring의 설정에 맞게 알아서 해준다. 이 얘기가 저번에 했던 이야기이다.

//기타 생략

<servlet>
    <servlet-name>dispatcher</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>

//기타 생략

Spring 3.1이하 혹은 servlet 3.0 이하 에서는 위와 같이 web.xml에 DispatcherServlet을 등록을 했어야 했다. 버전은 확실치는 않지만 아마 spring 3.1, servlet 3.0 이하 인걸로 기억하고 있다.
만약 위의 버전보다 높다면 굳이 xml에 DispatcherServlet 을 등록하지 않아도 된다. java config로 설정이 가능하다.
WebApplicationInitializer 인터페이스의 onStartup 메서드를 구현하면 된다.

public class WebAppInitializer implements WebApplicationInitializer {

  @Override
  public void onStartup(ServletContext servletContext) throws ServletException {
     //생략
  }
}

만약 위의 방법도 조금 귀찮다면 좀 더 쉬운 방법이 있다. AbstractAnnotationConfigDispatcherServletInitializer 클래스를 구현하면 된다. 하지만 이 클래스는 Spring 3.2부터 추가 된 클래스이다.

public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

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

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

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

Root Context와 servlet Context에 해당하는 클래스를 작성해주면 된다. WebApplicationInitializer인터페이스를 직접 구현하는 것보다는 좀 더 간편해졌다. 물론 AbstractAnnotationConfigDispatcherServletInitializer 클래스도 WebApplicationInitializer 인터페이스의 구현체이다. 좀 더 디테일하고 설정하고 싶다면 AbstractDispatcherServletInitializer 클래스를 사용해도 된다.

DispatcherServlet 을 설정 방법을 알아봤으니 Spring의 mvc를 간단하게 설정할 수 있는 방법을 살펴보자.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <mvc:annotation-driven/>

</beans>

xml을 사용해서 위와 같이 설정할 수 있다. 위의 XML Namespace는 아주 많은 설정을 자동으로 해준다. RequestMappingHandlerMapping, RequestMappingHandlerAdapter, ExceptionHandlerExceptionResolver, MessageConverter 등 Web에 필요한 빈들을 대부분 자동으로 설정 해주니 문서를 참고하면 되겠다.
xml설정 말고 java config로도 설정할 수 도 있는데 다음과 같이 설정을 하면 된다.

@Configuration
@EnableWebMvc
public class WebConfig {

}

위와 같이 설정하면 아까 <mvc:annotation-driven/>과 동일한 설정이 자동으로 이루워진다. 그리고 만약 기본설정 이외에 커스텀하게 설정할 부분이 있다면 WebMvcConfigurerAdapter 클래스를 상속하여 구현하면 된다.

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

}

Spring의 Adapter 클래스로 사용할 메서드만 오버라이딩해서 사용하면 된다. 필자가 예전에 Spring mvc와 관련해서 포스팅한 것이 있는데 그걸 참고 하면 되겠다.

그런데 Spring boot를 사용하면 굳이 @EnableWebMvc어노테이션은 필요 없이 사용하면 된다.

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

}

그냥 @Configuration만 설정하고 커스텀한 설정이 있다면 WebMvcConfigurerAdapter만 상속받아 구현해주면 된다.
그럼 왜 굳이 필요 없을까? Spring boot는 자동으로 설정해 주기 때문이다. 간단한 이유이다.
클래스 패스에 web과 관련된 라이브러리가 있다면 WebMvcAutoConfiguration 클래스가 동작하여 자동으로 web과 관련된 설정을 해준다.
하지만 Spring boot를 사용해도 @EnableWebMvc 어노테이션을 명시적으로 써줘도 된다. 만약 그런 설정을 원한다면 사용은 해도 되나 WebMvcAutoConfiguration클래스는 동작하지 않는다. 그럼 Spring boot가 설정해 놓은 기본설정은 동작하지 않게 된다.

그 이유는 @EnableWebMvc을 설정하면 자동으로 WebMvcConfigurationSupport 클래스가 자동으로 빈으로 등록이 되는데 WebMvcAutoConfiguration 클래스에는 다음과 같은 설정이 있기 때문이다.

//..
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
//..

WebMvcConfigurationSupport 클래스가 빈으로 등록되지 않을 경우에만 WebMvcAutoConfiguration 클래스를 동작하라는 뜻이다.

그래서 Spring boot (web)의 기본설정이 필요로 하지 않는다면 @EnableWebMvc 어노테이션을 사용해서 자신의 개발환경에 맞게 커스텀하게 만들면 된다. 하지만 필자의 경우에는 거의 그럴일이 없어 Spring boot가 자동으로 설정해주는 것 + WebMvcConfigurerAdapter 이용해 커스텀하게 설정을 자주 이용한다. 각자 원하는 방법으로 개발하면 되겠다.

오늘은 이렇게 Spring mvc 설정법과 spring boot의 mvc 설정법에 대해서 알아봤다.