[Spring] Spring Container의 구동 원리와 설정 파일에 대한 설명

DyungE_100·2022년 4월 11일
1

Spring

목록 보기
1/7

스프링 부트(Spring Boot)를 이용하면 xml파일을 따로 설정할 필요가 없지만, 기본적인 xml파일들에 대한 역할을 알아야 할 것 같아 정리하게 되었다.

0. 들어가기 전

0.1 서블릿 컨테이너와 스프링 컨테이너의 차이점

서블릿 컨테이너는 말 그대로 서블릿을 관리해주는 컨테이너(Container)다. 컨테이너(Container)라는 말 자체가 어떤 객체들을 관리해주는 의미이긴 하지만 스프링 컨테이너는 스프링 빈(Bean) 객체를 생성하거나 관리해주는 컨테이너이기도 하다. DispatcherServlet 또한 서블릿이긴 하나 서블릿 컨테이너가 보내는 요청을 맨 앞단에서 처리하는 Front Controller 역할을 할 뿐 스프링 컨테이너 안에 포함되어 있다.

결론적으로 스프링 컨테이너도 컨테이너(Container)의 일종이긴 하나 스프링 빈(Bean) 객체를 다룸과 동시에 서블릿(Servlet)도 관리하는 컨테이너라고 할 수 있겠다.

0.2 들어가기 전에 알아둘 것

서블릿도 자바로 만들어진 하나의 클래스이다. 이 서블릿 객체를 생성하고 다루는 것은 서블릿 컨테이너(=WAS)이다. 이클립스에서 서블릿 클래스(ex. HttpServlet 등)를 상속 받아 개발하면 web.xml 파일에 자동으로 등록된다.

WAS는 구동하면 맨 처음 WEB-INF/web.xml 파일을 로딩하고, 그 설정에 맞게 웹 애플리케이션 설정을 구성하게 된다.


1. 스프링 컨테이너는 어떻게 동작하는가? (by web.xml)

  1. Web Application이 실행되면, WAS는 web.xml을 맨 처음 읽게 된다.
    web.xml 파일은 모든 서블릿 컨테이너에 대한 기본적인 설정과 정보를 가지고 있고, 들어온 모든 요청을 DispatcherServlet으로 가도록 한다.

  2. web.xml에서 <context-param> 태그는 모든 서블릿과 필터가 공유하는 루트 스프링 컨테이너(= RootContext = ApplicationContext)를 정의하고, web.xml에 <listener> 태그에 등록된 ContextLoaderListener가 ApplicationContext.xml(또는 root-context.xml)에 따라 ApplicationContext를 생성한다.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://Java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<!-- 첫번째 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/spring/root-context.xml</param-value>
	</context-param>
	
	<!-- 두번째 -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- 세번째 -->
	<servlet>
		<servlet-name>appServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<!-- 네번째 -->
	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>

</web-app>
  1. ApplicationContext.xml에 등록되어 있는 설정에 따라 스프링 컨테이너가 구동되고, 이 때 개발자가 작성한 비즈니스 로직, DAO, VO 등의 개체가 생성된다.

  2. 그 이후 요청이 오게 되면 서블릿 컨테이너에선 Heap영역에서 적절한 서블릿을 찾게 되고, 만약 없을 경우에는 새로 생성하여 DispatcherServlet에게 요청을 하게 된다.

  3. 그 이후 요청을 처리하는 과정은 다른 글에서 이미 정리했으므로 생략.

결국 WAS(=Servlet Container)는 프로세스 하나에 배정되고, 그에 따라 웹 애플리케이션 하나(JVM)가 필요하다. 이에 요청 하나당 하나의 쓰레드가 형성되고, 이 요청들을 Thread별로 처리하도록 역할을 배정하는 것이 Thread Pool이라는 것이다.


2. 각 설정 파일에 대한 설명

1. web.xml

WAS가 실행되면 최초로 실행되는 파일이다. 그 이유 또한 WAS(즉, Servlet Container)가 서블릿들을 생성하고 어떤 서블릿이 어떤 요청(Mapping)을 할 것인지 등에 대한 정보들을 가지고 있기 때문이다.

2. ApplicationContext.xml(=root-Context.xml)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> 
  <!-- Root Context: defines shared resources visible to all other web components -->		
</beans>

스프링에 의해 생성되는 Bean 객체들에 대한 Spring DI Container이다.(흔히 말하는 DI Container는 이것을 지칭한다. 또는 IoC Container라고도 하지만 엄밀히 따지면 IoC보단 DI가 좀 더 Container에 대한 역할과 일맥상통하다.)

스프링 컨테이너에는 두 가지 유형이 있는데 BeanFactory 컨테이너와 이를 상속한 ApplicationContext 컨테이너이다.

  • 1) BeanFactory는 가장 기본적인 컨테이너 기능만 제공하며, 클라이언트의 요청(LookUp)에 의해서만 Bean 객체가 생성된다.(Lazy Loading 방식)

  • 2) 반면에 ApplicationContext는 BeanFactory를 상속하여 Bean 객체 관리 기능 외에도 트랜잭션 관리 등의 다양한 기능을 제공한다.

공통적으로 사용하는(=공유가 가능한) Bean들을 등록하는 Context이며, View와 관련이 없는 Repository(DAO)나 Service, DB 등과 같이 비즈니스 로직과 관련된 것들을 관리한다. 또한 컨테이너가 구동되는 시점에 바로 Bean 객체를 생성한다.(pre-loading 방식)

ApplicationContext의 구현 클래스 중 하나인 XmlWebApplicationContext는 웹 기반의 스프링 애플리케이션을 개발할 때 가장 많이 쓰이며 직접 생성하지 않는 컨테이너이다.

3. Servlet-Context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />
	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/resources/**" location="/resources/" />
	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>
	<context:component-scan base-package="com.company.devpad" />
</beans:beans>
  • <annotation-driven> : @Controller 어노테이션을 감지하여 해당 클래스를 Controller로 등록할 수 있도록 해주는 태그

  • <resources> : 정적인 html문서 같은 웹 리소스들의 정보를 기술하는 태그

  • <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> : Controller가 ModelAndView를 return하고 DispatcherServlet이 .jsp파일을 찾을 때 쓰이는 정보를 적은 태그. "home"이라는 문자열을 반환하면 /WEB-INF/views/ 경로에서 접미사가 .jsp인 해당 파일을 찾는다.
    예시) /WEB-INF/views/home.jsp

  • <context:component-scan> : Java 파일의 @Component로 등록된 Bean 객체를 찾도록 해주는 태그

스프링 DI 컨테이너(또는 IoC 컨테이너라고 불리기도 하는)를 부모 Context로 사용하는 Context이다. 주로 View와 관련된 자원으로 구성되며, DispatcherServlet이 사용하는 컨트롤러와 관련된 Bean을 등록하고 관리하는 컨테이너이다.





책<스프링 퀵 스타트>,
https://velog.io/@cateto/Spring-ApplicationContext.xml-%EC%99%80-ServletContext.xml,
https://devpad.tistory.com/24,
https://jypthemiracle.medium.com/servletcontainer%EC%99%80-springcontainer%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%B4-%EB%8B%A4%EB%A5%B8%EA%B0%80-626d27a80fe5,
https://jeong-pro.tistory.com/222,

0개의 댓글