du.study기록공간

configureHandlerExceptionResolvers, extendHandlerExceptionResolvers 차이점 본문

스프링

configureHandlerExceptionResolvers, extendHandlerExceptionResolvers 차이점

du.study 2019. 11. 22. 01:33
728x90

앞에 두개의 포스팅을 통하여 @ControllerAdvice,@ExceptionHandler를 통한 Exception 방법과 WebMvcConfigurer를 통하여 직접 등록한 Exception도 결국 같은 부분에서 Exception이 호출됩니다.

 

DispatcherServlet 에서 processDispatchResult 안의 해당 부분을 통하여 Exception을 뱉어내게 됩니다.

if (exception != null) {
	if (exception instanceof ModelAndViewDefiningException) {
		logger.debug("ModelAndViewDefiningException encountered", exception);
		mv = ((ModelAndViewDefiningException) exception).getModelAndView();
	}
	else {
		Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
		mv = processHandlerException(request, response, handler, exception);
		errorView = (mv != null);
	}
}

 

 

추가적으로 WebMvcConfigurer 부분에서 Exception 등록 방법은 두가지가 있습니다.

    //기존 default 로 등록되어있는 Exception 초기화    
    @Override
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
        resolvers.add(new ExceptionResolver());
    }
    
    // dafault를 보관하면서 가장 후순위에 새로운 Exception추가
    @Override
    public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
        resolvers.add(new ExceptionResolver());
    }

 

해당 유무에 따라서 DispatcherServlet handlerExceptionResolvers는 등록한 resolver만 가지게 될지, Default resolver를 가지고, 추가 구현된 resolver도 등록할지 결정되게 됩니다.

 

extendHandlerExceptionResolvers로 resolver를 등록했을때
configureHandlerExceptionResolvers 를 이용하여 resolver를 등록했을때

 

이부분을 결정짓는 건 @EnableWebMvc 안에서 호출되는 WebMvcConfigurationSupport의 아래 코드블럭에 의하여 다음과 같은 현상이 일어나게 됩니다.

@Bean
public HandlerExceptionResolver handlerExceptionResolver() {
	List<HandlerExceptionResolver> exceptionResolvers = new ArrayList<>();
	configureHandlerExceptionResolvers(exceptionResolvers);
	if (exceptionResolvers.isEmpty()) {
		addDefaultHandlerExceptionResolvers(exceptionResolvers);
	}
	extendHandlerExceptionResolvers(exceptionResolvers);
	HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite();
	composite.setOrder(0);
	composite.setExceptionResolvers(exceptionResolvers);
	return composite;
}

먼저 configureHandlerExceptionResolvers 를 호출하여 resolver를 등록하게 되고, 이경우 configureHandlerExceptionResolvers 에서 등록된 resolver가 없다면, 기본 resolver가 등록이 됩니다. 그 후, extendHandlerExceptionResolvers가 선언된 부분에 추가 resolver가 있다면 이부분을 등록해주면서 에러 resolver를 등록해줍니다.

 

개인적으로는 커스텀으로 만든 ExceptionResolver 하나만( @5807, @5692는 제가 등록한 ExceptionResolver) 등록하여 사용하고 있지만, 상황에 따라 AbstractHandlerExceptionResolver에서 order로 우선순위를 커스텀 할 수 있기에 기존 리졸버를 두고, 커스텀한 Resolver를 상위에 두어 먼저 처리되도록 하는것도 좋을 것 같습니다.

728x90
Comments