일반적으로 개발자로서 컨테이너를 검색하면 WEB Container, Servlet Container, Spring Container 등이 나온다.
이 컨테이너들을 이해하기 위해서는 컨테이너가 뭔지를 이해해야한다.
일반적인 IT에서의 컨테이너는 여기를 참고하자. https://cloud.google.com/learn/what-are-containers?hl=ko
Spring 컨테이너란
ApplicationContext를 스프링 컨테이너라고 합니다. ApplicationContext는 인터페이스입니다.
이 ApplicationContext의 구현체를 생성하고 메타정보를 읽음으로서 이 ApplicationContext타입의 객체는
컨테이너가 됩니다. 아래코드에서 context객체가 스프링컨테이너가 됩니다.
ApplicationContext context= new GenericXmlApplicationContext("some.xml");
이렇게 생성된 context객체(컨테이너)는 "some.xml" 에 정의된 빈을 저장하고 관리하는 역할을 합니다.
context객체가 빈을 가지고 있게 되고 필요할때마다 getBean 메소드를 이용해 전달합니다.
context.getBean(SomeService.class);
이 context객체안에서 빈들을 생성,사용 종료 등을 합니다.
실제로 Tomcat 시작 시
ContextLoaderLister, DispatcherServlet에서 ApplicationContext 객체를 생성해 빈들을 관리하게 됩니다.
@SuppressWarnings("serial")
public class DispatcherServlet extends FrameworkServlet {
ApplicationContext context=new GenericXmlApplicationContext("web.xml에서 설정한위치");
//실제론 DispatcherServlet에 이렇게 필드로 있진 않지만 DispatcherServlet어딘가에
//이런 ApplicationContext가 있다.
}
※ 빈이란 ??
위에서 말한 xml파일은 spring bean configuration 파일로 빈 관계를 정의한 xml 파일입니다.
이 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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="freeBoard" class="com.study.free.vo.FreeBoardVO"></bean>
</beans>
이 때 저 <bean>태그의 class에 있는 "com.study.free.vo.FreeBoardVO"는 java파일입니다.
즉, Spring Container가 이 xml을 읽으면서 FreeBoardVO 타입의 자바 객체를 생성하고 이를 관리합니다.
이렇게 Spring Container가 생성하고 관리하는 자바 객체를 빈이라고 합니다.
빈= 그냥 자바 객체 (인데 Spring Container가 생성한...)
스프링 컨테이너 계층 구조
이 스프링 컨테이너들은 부모-자식 관계의 계층 구조를 가질 수 있습니다.
자식에 속하는 컨테이너의 빈은 부모 컨테이너의 빈을 참조 할 수 있다. 즉 의존 객체로 사용할 수 있다.
반대로 부모 컨테이너에 속한 빈은 자식 컨테이너에 속한 빈을 참조 할 수 없다.
부모,자식관계 지정은 setParent()메소드를 사용한다.
GenericXmlApplicationContext parent= new GenericXmlApplicationContext("conf-parent.xml");
GenericXmlApplicationContext child= new GenericXmlApplicationContext();
child.setParent(parent);
child.load("conf-child.xml");
여기서 중요한건 child가 "conf-child.xml"을 로드해 빈을 만들려 할 때 parent의 빈을 참조해서(주입받아서)
만드는 빈이 있는 경우, 반드시 로드하기전에 부모관계를 지정해 줘야 한다는 것이다.
그렇지 않다면 , parent의 빈을 참조하지 못해(주입받지 못해) child의 빈을 만드는 과정에서 에러가 발생한다.
일반적으로 spring MVC에서 서버가 시작될 때 Spring 컨테이너는 다음과 같이 부모자식관계를 형성한다.