ErrorMvcAutoConfiguration 클래스에서 내부 클래스로 ErrorPageCustomizer를 가지고 있음
해당 객체를 bean으로 생성
@Bean
public ErrorPageCustomizer errorPageCustomizer(DispatcherServletPath dispatcherServletPath) {
return new ErrorPageCustomizer(this.serverProperties, dispatcherServletPath);
}
에러페이지를 생성해서 등록
public void registerErrorPages(ErrorPageRegistry errorPageRegistry) {
ErrorPage errorPage = new ErrorPage(this.dispatcherServletPath.getRelativePath(this.properties.getError().getPath()));
errorPageRegistry.addErrorPages(new ErrorPage[]{errorPage});
}
TomcatServletWebServerFactory의 errorPageRegistry이다
AbstractConfigurableWebServerFactory 인터페이스에서 에러페이지 추가
public void addErrorPages(ErrorPage... errorPages) {
Assert.notNull(errorPages, "ErrorPages must not be null");
this.errorPages.addAll(Arrays.asList(errorPages));
}
TomcatServletWebServerFactory에서 톰캣 시작
protected void configureContext(Context context, ServletContextInitializer[] initializers) {
TomcatStarter starter = new TomcatStarter(initializers);
if (context instanceof TomcatEmbeddedContext embeddedContext) {
embeddedContext.setStarter(starter);
embeddedContext.setFailCtxIfServletStartFails(true);
}
// 생략//
for(ErrorPage errorPage : this.getErrorPages()) {
//톰캣에 있는 에러페이지 가져옴
// 그리고 스프링 에러페이지 값을 톰캣 에러페이지에 넣고 톰캣에 등록함
org.apache.tomcat.util.descriptor.web.ErrorPage tomcatErrorPage = new org.apache.tomcat.util.descriptor.web.ErrorPage();
tomcatErrorPage.setLocation(errorPage.getPath());
tomcatErrorPage.setErrorCode(errorPage.getStatusCode());
tomcatErrorPage.setExceptionType(errorPage.getExceptionName());
context.addErrorPage(tomcatErrorPage);
}
StandardContext 클래스에서 에러페이지 추가함
public void addErrorPage(ErrorPage errorPage) {
if (errorPage == null) {
throw new IllegalArgumentException(sm.getString("standardContext.errorPage.required"));
} else {
String location = errorPage.getLocation();
if (location != null && !location.startsWith("/")) {
if (!this.isServlet22()) {
throw new IllegalArgumentException(sm.getString("standardContext.errorPage.error", new Object[]{location}));
}
if (log.isDebugEnabled()) {
log.debug(sm.getString("standardContext.errorPage.warning", new Object[]{location}));
}
errorPage.setLocation("/" + location);
}
this.errorPageSupport.add(errorPage);
this.fireContainerEvent("addErrorPage", errorPage);
}
}
public void add(ErrorPage errorPage) {
String exceptionType = errorPage.getExceptionType();
if (exceptionType == null) {
this.statusPages.put(errorPage.getErrorCode(), errorPage);
} else {
this.exceptionPages.put(exceptionType, errorPage);
}
}