스프링 MVC 설정(2) : @EnableWebMvc

de_sj_awa·2021년 6월 27일
0

일일이 빈으로 등록하기 보다는 애노테이션 기반 스프링 MVC를 사용할 때 편리한 웹 MVC 기본 설정을 할 수 있다.

2. @EnableWebMvc

@Configuration 
@EnableWebMvc 
public class WebConfig { 
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}

DelegatingWebMvcConfiguration.class를 보면 delegation 구조로 되어있기 때문에 손쉽게 기본 전략 객체(빈)을 커스터마이징할 수 있는 것이다.

@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {

	private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();


	@Autowired(required = false)
	public void setConfigurers(List<WebMvcConfigurer> configurers) {
		if (!CollectionUtils.isEmpty(configurers)) {
			this.configurers.addWebMvcConfigurers(configurers);
		}
	}

WebMvcConfigurationSupport.class에 HandlerMapping, Interceptor, MessageConverter 등 빈들이 등록되어 있다. WebMvcConfigurationSupport.classs는 스프링부트가 나오기 전부터 있었던 클래스이다.

public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware {

	private static final boolean romePresent;

	private static final boolean jaxb2Present;

	private static final boolean jackson2Present;

	private static final boolean jackson2XmlPresent;

	private static final boolean jackson2SmilePresent;

	private static final boolean jackson2CborPresent;

	private static final boolean gsonPresent;

	private static final boolean jsonbPresent;

	static {
		ClassLoader classLoader = WebMvcConfigurationSupport.class.getClassLoader();
		romePresent = ClassUtils.isPresent("com.rometools.rome.feed.WireFeed", classLoader);
		jaxb2Present = ClassUtils.isPresent("javax.xml.bind.Binder", classLoader);
		jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) &&
				ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader);
		jackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader);
		jackson2SmilePresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory", classLoader);
		jackson2CborPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.cbor.CBORFactory", classLoader);
		gsonPresent = ClassUtils.isPresent("com.google.gson.Gson", classLoader);
		jsonbPresent = ClassUtils.isPresent("javax.json.bind.Jsonb", classLoader);
	}

classpath에 어떤 라이브러리가 있느냐에 따라 스프링 MVC 구성 요소를 직접 빈으로 등록하지 않아도 기본 전략 객체 빈(DispatchServlet.properties)을 커스터마이징 해준다.

@Configuration
@ComponentScan
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
    
    @Bean
    public ViewResolver viewResolver(){
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }
}
public class WebApplication implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.setServletContext(servletContext); // 추가
        context.register(WebConfig.class);
        context.refresh();

        DispatcherServlet dispatcherServlet = new DispatcherServlet(context);
        ServletRegistration.Dynamic app = servletContext.addServlet("app", dispatcherServlet);
        app.addMapping("/app/*");
    }
}

또 실행시켜보면 @EnableWebMvc를 쓰기 이전과는 다르게 HandlerMappings의 우선순위가 1. RequestMappingHandlerMapping 2. BeanNameUrlMapping으로 조정되었고, HandlerAdpaters의 우선순위도 1. RequestMappingHandlerAdpater 2. HttpRequestHandlerAdapter 3. SimpleControllerHandlerAdater로 조정되어서 성능 상에서도 약간의 이점이 있을 수 있다.

참고

  • 인프런 : 스프링 웹 MVC(백기선)
profile
이것저것 관심많은 개발자.

0개의 댓글