일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 소프티어
- db
- softeer
- RequestBody
- FCM
- JPQL
- Service 계층 테스트
- Test
- enumSet
- 일상
- Coputer Science
- modelmapper
- JPA
- Test code
- 공룡책
- Test Doulbe
- 인프콘2023
- Spring
- MySQL
- 테크쇼
- ExceptionResolver
- OS
- proxyFactory
- Junit 5
- Java
- 자바
- Server
- backend
- mapstruct
- ObjectMapper
- Today
- Total
공부내용공유
@EnableWebMvc, WebMvcAutoConfiguration, WebMvcConfigurationSupport 알아보기 본문
@EnableWebMvc, WebMvcAutoConfiguration, WebMvcConfigurationSupport 알아보기
forfun 2024. 2. 7. 19:43서론
spring secutiry에서 mvc에 설정되어 있는 cors config를 어떻게 가져오는 알아보기 위해 코드를 뒤집어 까다가 mvc에 핵심적인 코드를 만났다.
spring으로 프로젝트를 진행하면 흔하게 접하는 EnableWebMvc, WebMvcConfigurer 등등을 보았고, 이번 mvc config에 있어서 핵심적인 클래스들, 작동 방식에 대해 이 글에서 정리할 예정이다.
본론
1. @EnableWebMvc
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}
위처럼 작성된 어노테이션이다.
해당 어노테이션에 들어가면 주석으로 상세한 설명들이 있는데 간단하게 요약하자면
- @Configuration 이 붙어있는 클래스에 해당 어노테이션을 사용하면 WebMvcConfigurationSupport 라는 spring mvc configuration을 import 한다.
(정확히는 어노테이션에서도 볼 수 있듯이 DelegatingWebMvcConfiguration를 import 한다.)
@Configuration
@EnableWebMvc
@ComponentScan(basePackageClasses = MyConfiguration.class)
public class MyConfiguration {
}
- imported 된 config를 커스터마이징 하고 싶다면 WebMvcConfigurer를 implements하고 메서드를 오버라이딩 하면 된다.
@Configuration
@EnableWebMvc
@ComponentScan(basePackageClasses = MyConfiguration.class)
public class MyConfiguration {
}
- @configuration 이 붙어있는 class들 중 1개에만 @EnableWebMvc 를 사용하는 것을 권고한다. 만약 여러개의 @Configuration 클래스에 @EnalbeWebMvc를 사용해야하는 경우가 있을 수 있다.
이럴때는 WebMvcConfigurationSupport를 직접 extends하여 커스텀 하는걸 권고한다.
@Configuration
@ComponentScan(basePackageClasses = { MyConfiguration.class })
public class MyConfiguration extends WebMvcConfigurationSupport {
@Override
public void addFormatters(FormatterRegistry formatterRegistry) {
formatterRegistry.addConverter(new MyConverter());
}
@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
// Create or delegate to "super" to create and
// customize properties of RequestMappingHandlerAdapter
}
}
2. WebMvcAutoConfiguration
@AutoConfiguration(after = {
DispatcherServletAutoConfiguration.class,
TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class })
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
public class WebMvcAutoConfiguration
설명에 Auto-configuration for Web MVC 라고 나와있다.
말 그대로 mvc에 필요한 설정을 자동으로 해주는 클래스이다.
단 주의해야 할 것이 있는데, @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) 어노테이션은 WebMvcConfigurationSupport bean이 없을 경우 해당 클래스가 생성됨을 의미한다.
즉 WebMvcConfigurationSupport 클래스를 만들거나 상속하게 되면 해당 자동 구성 기능은 사용할 수 없다.
3. WebMvcConfigurationSupport
@config가 붙은 클래스에 @EnalbeWebMvc 어노테이션을 사용하면 import 되는 spring mvc config 클래스이다.
해당 클래스 설명을 보면 mvc에 필요한 여러 클래스들을 등록해준다고 나와있는데 간단하게 리스트업 하면
- HandlerMappings
- RequestMappingHandlerMapping - 1순위
- HandlerMapping - 2순위…
- HandlerAdapters
- RequestMappingHandlerAdapter
- HttpRequestHandlerAdapter…
- HandlerExceptionsResolverComposite
- ExceptionHandlerExceptionResolver
- ResponseStatusExceptionResolver
- AntPathMatcher
- UrlPathHelper
- RequestMappingHandlerAdapter
- ExceptionHandlerExceptionResolver
정도가 있다. 자세한 내용은 직접 클래스를 찾아서 보면 될 것 같다.
4. DelegatingWebMvcConfiguration
위에서 봤던 @EnableWebMvc 를 통해 import 되는 class로 WebMvcConfigurationSupport 의 자식 클래스이다.
private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
이러한 필드를 가지고 있는데
WebMvcConfigurerComposite 클래스는
class WebMvcConfigurerComposite implements WebMvcConfigurer {
private final List<WebMvcConfigurer> delegates = new ArrayList<>();
}
이렇게 되어있고 WebMvcConfigurer 타입의 bean들을 스캔함으로 사용자가 spring mvc의 구성들을 커스터마이징 할 수 있게 해준다.
5. spring mvc customizing
@EnableWebMvc + WebMvcConfigurationSupport 사용
@Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry formatterRegistry) {
formatterRegistry.addConverter(new MyConverter());
}
}
WebMvcConfigurationSupport 사용
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
@Bean
@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
return super.requestMappingHandlerMapping();
}
}
WebMvcAutoConfiguration + WebMvcConfigurer 사용
@Configuration
public class WebMvcConfig implements WebMvcConfigurer, WebMvcRegistrations {
@Override
public void addFormatters(FormatterRegistry formatterRegistry) {
formatterRegistry.addConverter(new MyConverter());
}
}
결론
당분간 mvc config를 설정할 일이 없을 것 같긴 하지만 유익한 시간이었다!
언젠가는 mvc flow도 한번 쭉 정리할 예정이다!
'Spring > Spring MVC' 카테고리의 다른 글
java record JsonParseError (feat: requestBody) (1) | 2024.03.16 |
---|---|
RequestBody는 기본생성자가 필요없다.(feat: ParameterNamesModule) (1) | 2024.01.07 |
Spring 더 나은 예외처리 (0) | 2023.08.29 |