How Tomcat load spring web framework
environment
- Base project
- Eclipse -> File -> New -> Other -> Spring Getting Started Content -> spring-mvc-showcase
- Spring framework version : 4.2.2.RELEASE
- Web Application Server : Apache Tomcat 8.0.36
Spring web framework deployment
Web application에서 artifact를 servlet container에 올리는 과정을 deployment라고 표현한다. [code lang=text] 11-Apr-2017 02:49:11.284 정보 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory /Users/thdghgns/Documents/workspace/web-server/apache-tomcat-8.0.43/webapps/manager 11-Apr-2017 02:49:11.310 정보 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory /Users/thdghgns/Documents/workspace/web-server/apache-tomcat-8.0.43/webapps/manager has finished in 25 ms [/code]
Deployment Descriptor (web.xml)
container/engine으로 배포되는 artifact에 대한 설정파일 Java Platform에서는 component, module, 또는 application이 어떻게 배포되어야 하는지에 대해 설명한다. deployment tool에게 module 또는 application이 특정한 container option, security setting으로 deploy할 것을 알려주고, 특정 설정 요구사항에 대해 설명해준다. XML은 deployment descriptor 파일 작성을 위해 사용된 문법이다. Web application에서 deployment descriptor는 web.xml이라고 불리며 web application root의 WEB-INF 디렉토리 하위에 위치해야 한다($root/WEB-INF/web.xml) . Java EE application에서 deployment descriptor는 이름이 application.xml이어야 하며 application .ear file의 최상위 레벨의 META-INF 디렉토리 하위에 존재해야 한다. 참고자료 : 1. Wikipia 2. Oracle Weblogic 3. Google Appengine 4. Opendocs
How Tomcat Load Spring (sketch)
링크 : How Tomcat Load Spring (sketch)
ContextLoaderListener
역할
- Spring의 root WebApplicationContext의 시작/종료를 위한 Bootstrap listener.
ContextCleanupListener
와 같이 간단하게 ContextLoader에게 위임한다.
ServletContextListener
를 구현함으로써 servlet context에 대해 발생하는 이벤트를 받을 수 있게된다.
- 생성(초기화) :
public void contextInitialized(ServletContextEvent sce)
; - 삭제 :
public void contextDestroyed(ServletContextEvent sce)
javadoc
org.springframework.web.context.ContextLoaderListener
[code lang=java] /* Bootstrap listener to start up and shut down Spring’s root {@link WebApplicationContext}. Simply delegates to {@link ContextLoader} as well as to {@link ContextCleanupListener}. This listener should be registered after {@link org.springframework.web.util.Log4jConfigListener} in {@code web.xml}, if the latter is used. As of Spring 3.1, {@code ContextLoaderListener} supports injecting the root web application context via the {@link #ContextLoaderListener(WebApplicationContext)} constructor, allowing for programmatic configuration in Servlet 3.0+ environments. See {@link org.springframework.web.WebApplicationInitializer} for usage examples. @author Juergen Hoeller @author Chris Beams @since 17.02.2003 @see #setContextInitializers @see org.springframework.web.WebApplicationInitializer @see org.springframework.web.util.Log4jConfigListener */ public class ContextLoaderListener extends ContextLoader implements ServletContextListener { [/code]
javax.servlet.ServletContextListener
[code lang=java] /* Implementations of this interface receive notifications about changes to the servlet context of the web application they are part of. To receive notification events, the implementation class must be configured in the deployment descriptor for the web application. @see ServletContextEvent @since v 2.3 */ public interface ServletContextListener extends EventListener { [/code]
참고 :
- [ContextLoaderListener](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/context/ContextLoaderListener.html)
- [ServletContextListener](https://tomcat.apache.org/tomcat-8.5-doc/servletapi/javax/servlet/ServletContextListener.html)
web.xml 설정
[code lang=xml]
ContextLoader
역할
- root application context의 실제 초기화 작업을 수행
- web.xml에서
<context-param>
을 찾아서 context class type을 구분하여 `contextClass`로 설정. - web.xml에서
<param-name>contextConfigLocation</param-name>
을 찾아서 context instance의 값으로 전달- 허용되는 value
- commas 또는 spaces로 구분되는 여러개의 파일 경로
- Ant-style의 표현식(eg.”
WEB-INF/*Context.xml,WEB-INF/spring*.xml
“) - defualt : “
/WEB-INF/applicationContext.xml
“
- 다중 값이 적용되기 때문에 순서에 따라 override가 됨.
- 허용되는 value
참고 : Spring framework javadoc - ContextLoader
How Tomcat Load Spring (detail)
링크 : How Tomcat Load Spring (detail)
- Web Application Server(tomcat)이 DD(web.xml)을 읽어서 Listener(
ClassLoaderListener
)를 등록 - Web Application Server가 Servlet Context를 생성하면 servlet context 초기화 이벤트(ServletContextEvent)가 발생하고, 이벤트를
ClassLoaderListener
가 이벤트를 받아서contextInitialized()
를 실행한다.- 이때 받은
ServletContextEvent
에서ServletContext
를 꺼내고 보면 실제 context는org.apache.catalina.core.ApplicationContext
이다.
- 이때 받은
- 현재
context==null
이기 떄문에 context를 생성한다.- 별다른 설정이 없을 경우
XmlWebApplicationContext
가 기본.
- 별다른 설정이 없을 경우
- context가 active가 아니고 root이기 때문에 parent==null이고 parent를 주려고 찾아도 없다.
- ServletContext를 WebApplicationContext의 servlet context로 설정한다.
- 에 설정된 contextConfigLocation 설정 파일 위치를 읽어서
StandardServletEnvironment
을 생성한다.StandardServletEnvironment
는 내부적으로StandardEnvironment
를 확장하고,StandardEnvironment
는 내부적으로AbstractEnvironment
를 확장한다.- property source를 customize.
- servletConfigInitParams
- servletContextInitParams
- jndiProperties
- systemProperties
- systemEnvironment
- property source를 init(새로 만들고 replace)
- servletContextInitParams
- refresh()
- refresh 준비
- active로 변경
- property source를 다시 init
- ConfigurableListableBeanFactory 획득. 없으면 생성
- XmlBeanDefinitionReader
- environment 설정
- resource loader설정
- entity resolver 설정
- init
- reader로 xml resource에서 bean definition을 읽음.
- bean을 읽고
- resource 닫고
- XmlBeanDefinitionReader
- postProcessBeanFactory
- invokeBeanFactoryPostProcessors
- registerBeanPostProcessors
- initMessageSource
- initApplicationEvntMulticaster
- onRefresh -> theme 설정
- registerListeners
- finishBeanFactoryInitialization
- bean 생성
- refresh 준비
- Filter 등록
- 등록할 때
StandardServletEnvironment
를 다시 customize하면서 property source 다시 설정
- 등록할 때
- DispatcherServlet 등록
- servletContext 생성
- 등록할 때
StandardServletEnvironment
를 다시 customize하면서 property source 다시 설정
- property source를 customize.
ApplicationContext의 특성
Application Context vs Bean Factory
역할 및 기능
- Bean Factory :
- Bean instantiation/wiring
- Application Context :
- Bean instantiation/wiring
- Automatic BeanPostProcessor registration
- Automatic BeanFactoryPostProcessor registration
- Convenient MessageSource access (for i18n)
- ApplicationEvent publication
Application Context Structure
### Application Context Inheritance Root Web Application Context : ContextLoader
가 생성한 Application Context DispatcherServlet Web Application Context : Root Web Application Context
를 부모로 하는 child application context> parent에서는 child를 바라보지 못하고, child는 parent를 바라볼 수 있다.> 그래서 parent는 child context에 정의된 bean을 사용할 수 없고, child는 parent에 정의된 bean을 사용한다. 이때 한 parent에 속하는 child는 parent의 bean을 공유한다.> BeanPostProcessors, BeaFactoryPostProcessors는 child에게 상속되지 않는다. 이유는 scope가 per-container
이기 때문이다.참고자료 : 7.8.1 Customizing beans using a BeanPostProcessor### Root Web Application Context vs DispatcherServlet Web Application Context일반적으로 Root Applicaion Context에는 Services, DAOs와 같은 bean이 정의되고, DispatcherServlet Web Applicaion Context에는 servlet을 사용하는 Controller bean이 등록된다.
Application Context Inheritance
- Root Web Application Context :
ContextLoader
가 생성한 Application Context - DispatcherServlet Web Application Context : Root Web Application Context를 부모로 하는 child application context
parent에서는 child를 바라보지 못하고, child는 parent를 바라볼 수 있다. 그래서 parent는 child context에 정의된 bean을 사용할 수 없고, child는 parent에 정의된 bean을 사용한다. 이때 한 parent에 속하는 child는 parent의 bean을 공유한다. BeanPostProcessors, BeaFactoryPostProcessors는 child에게 상속되지 않는다. 이유는 scope가 ‘per-container’이기 때문이다. 참고자료 : 7.8.1 Customizing beans using a BeanPostProcessor
Root Web Application Context vs DispatcherServlet Web Application Context
일반적으로 Root Applicaion Context에는 Services, DAOs와 같은 bean이 정의되고, DispatcherServlet Web Applicaion Context에는 servlet을 사용하는 Controller bean이 등록된다. 참고자료 : deroneriksson.com