-
스프링 환경에서 웹 애플리케이션 설정 메커니즘 정리스터디 노트 2023. 11. 1. 14:52
웹 애플리케이션의 설정 메커니즘에 대해 스터디해보도록 하겠습니다.
다음은 @EnableWebMvc와 DelegatingWebMvcConfiguration 클래스의 일부분입니다.
// EnableWebMvc Annotation interface @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Documented @Import({DelegatingWebMvcConfiguration.class}) public @interface EnableWebMvc { }
// DelegatingWebMvcConfiguration class public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport { private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite(); public DelegatingWebMvcConfiguration() { } ... }
EnableWebMvc를 보면 @Import 어노테이션을 사용해 DelegatingWebMvcConfiguration 클래스를 지정하고 있습니다.
그래서 @EnableWebMVc 어노테이션이 선언된 자바 설정 클래스가 로딩될 때 DelegatingWebMvcConfiguration 클래스도 같이 로딩됩니다.
즉, DelegatingWebMvcConfiguration도 실행된다고 생각하면 됩니다.
DelegatingWebMvcConfiguration 클래스를 보면 WebMvcConfigurationSupport를 상속하고 있다는 것을 알 수 있습니다.
또한 클래스 내부 변수에 WebMvcConfigurerComposite 타입의 configurers를 포함하고 있죠.
이 두 클래스가 스프링 웹 애플리케이션을 설정하는데 가장 중요한 역할을 하게 됩니다.
WebMvcConfigurationSupport 클래스는 스프링 웹 애플리케이션의 기본 기능을 설정하는 역할을 합니다.
예를 들어 DispatcherServlet이 사용자 요청을 컨트롤러 클래스의 핸들러 메서드를 매핑하는 RequestMappingHandlerMapping을 설정합니다.
또한 적절한 핸들러의 메서드를 찾으면 사용자 요청을 전달하는 RequestMappingHandlerAdapter 객체를 생성하고 설정합니다.
@RequestBody나 @ResponseBody 어노테이션이 선언된 객체를 변경하는 HttpMessageConverter 객체들도 설정을 합니다.
이외에도 뷰나 예외를 처리하는 HandlerExceptionResolver를 설정하는 등 DispatcherServlet과 같이 동작하는 여러 컴포넌트를 생성하여 기본값으로 설정합니다.
DelegatingWebMvcConfiguration의 내부 속성인 WebMvcConfigureComposite은 List<WebMVcConfigurer>를 감싼 합성 클래스입니다. 즉 내부에 WebMvcConfigurer 리스트를 포함한 래핑 클래스이죠.
그래서 내부 WebMvcConfigurer를 호출할 수 있는 메서드도 제공을 합니다.
예를 들어 addFormatter()메서드는 List<WebMvcConfigurer>의 엘리먼트인 WebMvcConfigurer의 addFormatter() 메서드들을 반복해 호출합니다.
DelegatingWebMvcConfiguration은 프레임워크를 설정할 때 WebMvcConfigureComposite의 메서드를 호출하면서 WebMvcConfigurer의 값들을 참조해 설정합니다.
이 과정에서 스프링 프레임워크는 WebMvcConfigurer 인터페이스를 사용해 개발자가 프레임워크 설정 과정에 직접적으로 개입할 수 있는 방법을 제공합니다.
바로 WebMvcConfigurer 인터페이스를 구현한 구현 클래스를 스프링 빈으로 등록하면 스프링 프레임워크가 이를 WebMvcConfigureComposite에 포함시키고, 이는 애플리케이션이 실행되며 프레임워크 설정과정을 거치고 의도대로 설정된 WebMvcConfigurer 구현체의 값을 사용하게 됩니다.
사용자가 구현한 메서드를 애플리케이션이 다시 호출하는 구조라 WebMvcConfigurer의 메서드를 콜백메서드라고 합니다.
또한 개발자는 모든 메서드를 구현할 필요 없이 필요한 메서드만 구현하면 됩니다.
스프링 부트 프레임워크의 자동 설정 클래스인 WebMvcAutoConfiguration의 코드를 살펴봅시다.
// WebMvcAUtoConfiguration class @AutoConfiguration( after = {DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class} ) @ConditionalOnWebApplication( type = Type.SERVLET ) @ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class}) @ConditionalOnMissingBean({WebMvcConfigurationSupport.class}) @AutoConfigureOrder(-2147483638) @ImportRuntimeHints({WebResourcesRuntimeHints.class}) public class WebMvcAutoConfiguration { ... public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware { } ... public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware { } ... }
스프링 부트 프레임워크는 WebMvcAutoConfiguration 클래스가 프레임워크에 필요한 컴포넌트들을 자동 설정해줍니다.
이는 spring-boot-starter-web 의존성만 설정하면 애플리케이션을 실행할 때 동작하게 됩니다.
스프링 부트의 경우 전통적인 서블릿 방식의 웹 애플리케이션과 비동기 방식의 웹플럭스 방식의 웹 애플리케이션을 설정할 수 있는데 기본은 서블릿 타입의 웹 애플리케이션을 사용합니다.
위 예제에서 @ConditionalOnWebApplication의 SERVLET이 그것입니다.
바로 밑에 @ConditionalOnClass 설정은 클래스패스에 Servlet, DispatcherServlet, WebMvcConfigurer class들이 있는 경우 WebMvcAutoConfiguration이 실행하도록 하는 어노테이션입니다.
@ConditionalOnMissingBean 어노테이션은 ApplicationContext에 WebMvcConfigurationSupport 클래스 타입의 빈이 없을 경우 기본적으로 WebMvcAutoConfiguration이 실행되도록 설정하는 어노테이션입니다.
WebMvcAutoConfiguration 클래스 내부엔 자동 설정을 한느 두 개의 중요 이너 클래스가 있는데 WebMvcAutoConfigurationAdapter와 EnableWebMvcConfiguration이 그것입니다.
WebMvcAutoConfigurationAdapter는 앞서 본 WebMvcConfigurer 인터페이스를 구현하는 구현체로 이는 웹 애플리케이션을 설정할 수 있는 콜백메서드 인터페이스나는 것을 봤었습니다.
그러므로 WebMvcAutoConfigurationAdapter는 스프링 프레임워크의 DispatcherSerlvet을 설정하는 클래스입니다.
EnableWebMvcConfiguration은 @EnableWebMvc가 실행하는 DelegationWebMvcConfiguration을 상속받습니다.
이는 스프링 부트 프레임워크에서 사용자가 직접 @EnableWebMvc 애너테이션을 선언하지 않아도 DelegationWebMvcConfiguration이 실행되는 것을 의미합니다.
스프링 웹 MVC 프레임워크를 직접 설정하는 방법과 부트를 사용해 자동 설정하는 방법을 비교하면 설정 원리와 핵심 클래스는 서로 같은 방식을 사용합니다만, 스프링 부트에서 조금 더 편하게 자동 설정을 사용할 수 있고 WebMvcAutoConfiguration 같은 자동 설정 클래스에서 제공하는 보편적인 설정을 사용할 수 있다는 장점이 있습니다.
다시 정리를 해보면, 스프링 웹 MVC 프레임워크를 직접 설정하려면 WebMvcConfigurer 구현체를 만들어야 합니다.
앞서 설명한 두 방식 모두 DeligationWebMvcConfiguration을 사용하여 설정하기 때문에 이를 사용하려면 WebMvcConfigurer 인터페이스를 구현하는 클래스를 먼저 만들고 콜백 메서드 중 필요한 메서드를 구현해야 합니다.
마지막으로 WebMvcConfigurer 구현 클래스에 @Configureation 어노테이션을 선언하여 자바 설정 클래스로 만들면 스프링 웹 MVC 애플리케이션 기동 시 만들어진 WebMvcConfigurer를 사용하여 설정할 수 있게 됩니다.
Reference
'스프링부트로 개발하는 MSA 컴포넌트'를 참고하여 작성된 컨텐츠 임을 밝힙니다.
'스터디 노트' 카테고리의 다른 글
MongoDB + Docker 설치 및 기본 동작 방법 bash: mongo: command not found (1) 2023.11.09 도커 + 카프카 명령어 (0) 2023.11.08 제네릭의 변성, 공변, 반공변 등등의 개념들 (0) 2023.10.30 REST API의 개념과 설계 방법 (0) 2023.10.24 Spring MVC Component의 동작구조(그림주의) (0) 2023.10.23