Servlet 컨테이너가 생성되면 어떻게 AbstractAnnotationConfigDispatcherServletInitializer 을 상속받아 작성한 클래스를 읽고 Dispatcher Servlet을 등록하고 초기화 작업을 할 수 있을까?
ServletContainerInitializer 를 구현한 SpringServletContainerInitializer 클래스를 잘 살펴보자
@HandlesTypes({WebApplicationInitializer.class})
public class SpringServletContainerInitializer implements ServletContainerInitializer {
public SpringServletContainerInitializer() {
}
public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException {
List<WebApplicationInitializer> initializers = Collections.emptyList();
Iterator var4;
if (webAppInitializerClasses != null) {
initializers = new ArrayList(webAppInitializerClasses.size());
var4 = webAppInitializerClasses.iterator();
while(var4.hasNext()) {
Class<?> waiClass = (Class)var4.next();
if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) && WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
try {
((List)initializers).add((WebApplicationInitializer)ReflectionUtils.accessibleConstructor(waiClass, new Class[0]).newInstance());
} catch (Throwable var7) {
throw new ServletException("Failed to instantiate WebApplicationInitializer class", var7);
}
}
}
}
if (((List)initializers).isEmpty()) {
servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
} else {
servletContext.log(((List)initializers).size() + " Spring WebApplicationInitializers detected on classpath");
AnnotationAwareOrderComparator.sort((List)initializers);
var4 = ((List)initializers).iterator();
while(var4.hasNext()) {
WebApplicationInitializer initializer = (WebApplicationInitializer)var4.next();
initializer.onStartup(servletContext);
}
}
}
}
서블릿 컨테이너가 실행될 때 @HandlesTypes 어노테이션을 통해 WebApplicationInitializer.class 의 클래스를 모두 찾아 onStartup() 메소드의 인자로 넣어준다.
즉 내가 작성한 AbstractAnnotationConfigDispatcherServletInitializer 을 상속받은 클래스를 찾아 onStartup()메소드의 인자로 넣어줄 수 있는 것이다.
AbstractAnnotationConfigDispatcherServletInitializer 는 결국 WebApplicationInitializer 을 구현한 클래스니 . .
onStartup() 함수 내부에
while(var4.hasNext()) {
WebApplicationInitializer initializer = (WebApplicationInitializer)var4.next();
initializer.onStartup(servletContext);
}
이 부분에서 WebApplicationInitializer 의 onStartup을 Servlet Context를 넘겨 실행시키면서 Dispatcher Servlet이 등록된다.
- AbstractDispatcherServletInitializer
public abstract class AbstractDispatcherServletInitializer extends AbstractContextLoaderInitializer {
public static final String DEFAULT_SERVLET_NAME = "dispatcher";
public AbstractDispatcherServletInitializer() {
}
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
// 이부분
this.registerDispatcherServlet(servletContext);
}
.
.
.
}
Web.xml을 사용하지 않는 Java-Base configuration의 작동원리에 대해서 코드를 뜯어 보았다.
스프링 프레임워크 해부하는 것도 재밌다.
'백엔드 > Spring Framework' 카테고리의 다른 글
| [Spring] Spring Security - 스프링 시큐리티 아키텍쳐 (0) | 2024.09.03 |
|---|