-
Notifications
You must be signed in to change notification settings - Fork 3
Open
Description
- Root WebApplicationContext
- Servlet 에 의해 생성
- Servlet WebApplicationContext
- DispatcherServlet 에 의해 생성
- Servlet WebApplicationContext 에서 빈을 조회할 수 없는 경우 Root WebApplicationContext를 조회
web.xml 로 정의
<web-app>
<!-- Root -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/root-context.xml</param-value>
</context-param>
<!-- Servlet -->
<servlet>
<servlet-name>app1</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/app1-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>app1</servlet-name>
<url-pattern>/app1/*</url-pattern>
</servlet-mapping>
</web-app>Java 로 정의:
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
// Root
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { RootConfig.class };
}
// Servlet
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { App1Config.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/app1/*" };
}
}web.xml 대신 자바 정의를 사용할 수 있는 이유
- 서블릿 컨테이너가 초기화 될 때
spring-web에서 정의한org.springframework.web.SpringServletContainerInitializer가 실행된다.javax.servlet.ServletContainerInitializer를 구현@HandleTypes값으로org.springframework.web.WebApplicationInitializer를 지정- 서블릿이 클래스패스에 존재하는
org.springframework.web.WebApplicationInitializer의 구현체를 스캔해서onStartup메소드의 파라미터로 전달
AbstractAnnotationConfigDispatcherServletInitializer는org.springframework.web.WebApplicationInitializer를 구현org.springframework.web.SpringServletContainerInitializer가 여러개의org.springframework.web.WebApplicationInitializer를 호출하는 방식으로 작동한다.- 서블릿 컨테이너에
war를 배포할 경우 사용되는 시나리오
스프링 부트에서 컨텍스트가 초기화되는 방법
- 스프링 부트는 Embedded Tomcat 을 사용하기 때문에 위 시나리오와는 다른 방식으로 스프링 컨테이너가 초기화된다.
- 스프링 컨테이너가 초기화 된 뒤 내장 톰캣이 실행된다.
org.springframework.web.SpringServletContainerInitializer대신org.springframework.boot.web.servlet.ServletContextInitializer를 구현하는 빈을 등록한다.- 스프링 부트에서는
org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext를 사용한다.createWebServer()에서 웹 서버를 생성하고org.springframework.boot.web.servlet.ServletContextInitializer를 찾아서 서블릿 컨텍스트를 초기화하는데 사용한다.org.springframework.boot.web.servlet패키지에 있는~RegistrationBean은org.springframework.boot.web.servlet.ServletContextInitializer를 상속받는다.ServletRegistrationBean,FilterRegistrationBean,ServletListenerRegistrationBean을 사용해서 서블릿 컨테이너를 초기화 할 수 있다.
Root WebApplicationContext 와 Servlet WebApplicationContext 가 연결되는 지점:
DispatcherServlet은FrameworkServlet을 상속 받는다AnnotationConfigApplicationContext는GenericApplicationContext를 상속받는다.WebApplicationInitializer를 구현한WebApplicationInitializer의registerDispatcherServlet(ServletContext servletContext)메소드에서DispatcherServlet을 생성한다.javax.servlet.GenericServlet의init(ServletConfig config)메소드가 실행된다org.springframework.web.servlet.HttpServletBean의init()메소드가 실행된다.org.springframework.web.servlet.FrameworkServletinitServletBean()메소드가 실행된다.initWebApplicationContext()메소드가 실행된다.- 서블릿 컨텍스트에서
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE로 등록된 attribute 를 조회한다. -> Root Context - DispatcherServlet에 생성된 WebApplicationContext 객체의
setParent()메소드를 호출해서 Root Context 와 연결한다.
- 서블릿 컨텍스트에서
Metadata
Metadata
Assignees
Labels
No labels
