JAVA

Spring Web Application 구동

wooyit 2022. 7. 21. 13:30

1. 웹 어플리케이션이 실행되면 Tomcat(WAS)에 의해 web.xml 로딩

2. web.xml에 등록되어있는 ContextLoaderListener 생성.

web.xml
<!-- Spring Context Listener -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>



' ContextLoaderListener는 ServletContextListener 인터페이스를 구현하고 있으며, ApplicationContext를 생성한다.

public class ContextLoaderListener implements ServletContextListener {
	private ContextLoader contextLoader;
  
    public void contextInitialized(ServletContextEvent event) {
        this.contextLoader = createContextLoader();
        this.contextLoader.initWebApplicationContext(event.getServletContext());
    }
    ...
}


' initWebApplicationContext : return Type WebApplicionContext이며 WebApplicionContext는 *ApplicationContext를 상속

public WebApplicationContext initWebApplicationContext(ServletContext servletContext) throws IllegalStateException, BeansException {
	..
}

public interface WebApplicationContext extends ApplicationContext {
	..
}


' Tomcat 실행시 ApplicationContext 생성로그

[2022-07-21 11:19:01] [INFO] [org.springframework.web.context.ContextLoader.initWebApplicationContext(189)]
=> Root WebApplicationContext: initialization started


* ApplicationContext: IoC엔진이며, 빈의 생명주기를 담당한다.

ApplicationContext를 스프링 컨테이너라고 한다. ApplicationContext는 BeanFactory 인터페이스의 하위 인터페이스다.
즉, ApplicationContext는 BeanFactory에 부가기능을 추가한 것이다.
스프링 컨테이너는 기본적으로 빈을 싱글톤으로 관리해준다. 따라서 싱글톤 컨테이너라고 불리기도 한다. 스프링 컨테이너가 빈을 싱글톤으로 관리해주면서 기존 싱글톤 패턴의 문제점(싱글톤 패턴 구현을 위한 코드가 추가되어야함, 구체 클래스에 의존, 유연성이 떨어짐 등..)은 없어지고, 싱글톤의 장점(매번 인스턴스를 생성할 필요없이 단 하나만 생성해서 비용을 줄일 수 있다.)만 가져갈 수 있다.


3. ContextLoaderListener가 root-context.xml을 로딩

ContextLoaderListener
서블릿을 초기화하는 용도로 사용
contextConfigLocation 파라미터를 사용하여, load할 수 있는 설정파일을 지정할 수 있다.
<!-- Spring config file path definition -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/applicationContext*.xml</param-value>
</context-param>


* Tomcat 실행 시 context.xml 설정 로딩 로그

[2022-07-21 11:19:01] [INFO] [org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(323)] => Loading XML bean definitions from ServletContext resource [/WEB-INF/config/applicationContext-A.xml]
[2022-07-21 11:19:01] [INFO] [org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(323)] => Loading XML bean definitions from ServletContext resource [/WEB-INF/config/applicationContext-C.xml]
[2022-07-21 11:19:01] [INFO] [org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(323)] => Loading XML bean definitions from ServletContext resource [/WEB-INF/config/applicationContext-B.xml]
[2022-07-21 11:19:01] [INFO] [org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(323)] => Loading XML bean definitions from ServletContext resource [/WEB-INF/config/applicationContext.xml]


4. root-context.xml 등록되어 있는 설정에 따라 Spring Container(ROOT) 구동.

DAO, VO, Service 객체 생성


5. 사용자가 URL을 입력하면 HTTP Request가 Servlet Container로 전송

6. 요청을 전송받은 Servlet Container는 HttpServletRequest, HttpServletReponse 객체를 생성

7. web.xml을 기반으로 사용자가 요청한 URL이 어느 서블릿에 대한 요청인지 찾기

8. Servlet이 servlet-context.xml을 로딩

web.xml - servlet 설정
<!-- Spring DispatcherServlet Config -->
<servlet>
<servlet-name>controller</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/spring/servlet-context.xml</param-value> </init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>controller</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

servlet-context.xml 설정
<!-- enable autowire -->
<context:annotation-config />
<!-- enable component scanning (beware that this does not enable mapper scanning!) -->
<context:component-scan base-package="test">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/> </context:component-scan>


10. 해당 서블릿에서 service 메소드를 호출한 후 클라이언트의 GET, POST 여부에 따라 doGet(), doPost()를 호출

11. doGet(), doPost() 메소드는 동적 페이지를 생성한 후 HttpServletReponse 객체에 응답을 전송

12. 응답이 끝나면 HttpServletRequest, HttpServletReponse 두 객체를 소멸

Reference

'JAVA' 카테고리의 다른 글

AXON Framework 구현 방법  (1) 2023.02.24
JAVA applicationEventPublisher로 순환참조 해결!  (0) 2023.02.13
웹 스크래퍼, 크롤링 Java 구현  (0) 2023.02.08
JAVA SE vs JAVA EE 개념  (0) 2022.07.25
서블릿(Servlet)이 뭐지..?  (0) 2022.07.22