IoC 컨테이너
- 
스프링 어플리케이션에서는 오브젝트의 생성과 관계설정, 사용, 제거 등의 작업을 애플리케이션 코드 대신 독립된 컨테이너가 담당 
- 
컨테이너가 코드 대신 오브젝트에 대한 제어권을 갖고 있어서 스프링 컨테이너를 IoCInversion of Control 컨테이너 라고도 함 
- 
스프링에서 IoC를 담당하는 컨테이너를 빈 팩토리 또는 애플리케이션 컨텍스트 라고 부르기도 함 - 
오브젝트의 생성과 오브젝트 사이의 럼타임 관계를 설정하는 DI 관점으로 볼 때 빈 팩토리 라고 함, 하지만 스프링 컨테이너는 단순한 DI 작업보다 더 많은 일을 함 
- 
DI를 위한 빈 팩토리에 엔터프라이즈 애플리케이션을 개발하는 여러 가지 컨테이너 기능을 추가한 것을 애플리케이션 컨텍스트 라고 함 
 
- 
- 
스프링의 IoC 컨테이너는 일반적으로 애플리케이션 컨테스트 를 말함 
- 
스프링에서 빈 팩토리( BeanFactory)와 애플리케이션 컨테스트(ApplicationContext) 인터페이스가 정의되어 있음- 
ApplicationContext인터페이스는BeanFactory인터페이스를 상속한 서브인터페이스TheApplicationContext.javain spring-context-4.3.21.RELEASEpublic interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
- 
실제로 스프링 컨테이너(또는 IoC 컨테이너)라고 말하는 것은 바로 이 ApplicationContext인터페이스를 구현한 클래스의 오브젝트
 
- 
- 
스프링 애플리케이션은 최소한 하나 이상의 애플리케이션 컨텍스트 오브젝트 를 갖고 있음 
IoC 컨테이너를 사용하는 애플리케이션 생성하기
- 
만들어진 컨테이너가 본격적인 IoC 컨테이너로서 동작하려면 POJOPlain Old Java Object 클래스 와 설정 메타정보 가 필요함 - 
POJO 코드를 설계할 때는 일단 유연한 변경 가능성을 고려해서 만듬 
- 
POJO는 특정 기술과 스펙에서 독립적일뿐더러 의존관계에 있는 다른 POJO와 느슨한 결합Loose Coupling을 갖도록 만들어야 함 
 
- 
- 
애플리케이션에서 사용할 것을 선정하고 이를 IoC 컨테이너가 제어할 수 있도록 적절한 메타정보 를 만들어야 함 
- 
IoC에서 가장 기초적인 역할은 오브젝트를 생성하고 관리하는 것 - 
스프링 컨테이너가 관리하는 오브젝트를 빈bean 이라고 부름 
 
- 
- 
스프링이 XML에 담김 내용을 읽어서 설정 메타정보로 활용하는 것이지, XML로 된 설정 메타정보를 가졌다는 말은 틀림 - 
스프링의 설정 메타정보는 BeanDefinition인터페이스로 표현되는 순수한 추상 정보
- 
즉, XML에 종속되지 않고 BeanDefinition으로 정의되는 스프링의 설정 메타 정보의 내용을 표현한 것이 있다면 어떤 형식이든 사용 가능
 
- 

WebApplicationContext
- 
스프링 애플리케이션에서 사장 많이 사용되는 애플리케이션 컨텍스트 
- 
웹에서 자바 VM 에게 main()메소드를 가진 클래스를 시작시켜 달라고 요청할 수 없음, 게다가 사용자도 여럿이며 동시에 웹 애플리케이션 사용- 
웹 환경에서는 main()메소드 대신 서블릿 컨테이너 가 브라우저로부터 오는 HTTP 요청을 받아서 해당 요청에 매핑되어 있는 서블릿을 실행해주는 방식으로 동작
- 
서블릿이 일종의 main()메소드와 같은 역할
 
- 
- 
스프링은 웹 환경에서 애플리케이션 컨텍스트를 생성하고 설정 메타정보를 초기화하고, 클라이언트로부터 들어오는 요청마다 적절한 빈을 찾아서 실행시켜주는 기능을 가진 DispatcherServlet을 제공- 
web.xml에 등록하는 것만으로 웹 환경에서 스트링 컨테이너가 만들어지고 애플리케이션을 실행하는 데 필요한 대부분의 준비가 가능함
 
- 
- 
몇 개의 서블릿이 중앙집중식으로 모든 요청을 다 받아서 처리하는 방식을 프론트 컨트롤러 패턴 이라고 함 
- 
서버에서 작동하는 애플리케이션에서 스프링 IoC 컨테이너를 사용하는 방법은 크게 3 가지 - 
엔터프라이즈 애플리케이션 레벨에 두는 방법(1 가지) 
- 
웹 모듈 안에 컨테이너를 두는 것(2 가지) 일반적으로 위 두가지 방식을 모두 사용해 컨테이너를 만듬. 
 그래서 스프링 웹 어플리케이션에는 두 개의 컨테이너, 즉WebApplicationContext오브젝트가 만들어짐- 
스프링 애플리케이션의 요청을 처리하는 서블릿 안에서 만들어지는 것 
- 
웹 애플리케이션 레벨에서 만들어지는 것 
 
- 
 
- 
- 
웹 애플리케이션 레벨에 등록되는 컨테이너는 보통 루트 웹 애플리케이션 컨텍스트 라고 함 - 
서블릿 레벨에 등록되는 컨테이너들의 부모 컨텍스트가 됨 
- 
일반적으로 전체 계층구조 내에서 가장 최상단에 위치하기 때문 
 
- 
웹 애플리케이션의 컨텍스트 구성 방법
- 
서블릿 컨텍스트와 루트 애플리케이션 컨텍스트 계층구조 - 
컨텍스트 계층구조를 만드는 것 
- 
스프링 웹 기능을 사용하는 경우 적용 가능 
 
- 
- 
루트 애플리케이션 컨텍스트 단일구조 - 
컨텍스트를 하나만 사용하는 방법 
- 
스프링 웹 기술을 사용하지 않을 때 적용 가능한 방법 
 
- 
- 
서블릿 컨텍스트 단일구조 - 
컨텍스트를 하나만 사용하는 방법 
- 
스프링 웹 기능을 사용하는 경우 적용 가능 
- 
루트 애플리케이션 컨텍스트를 생략하는 경우도 있음 
- 
서블릿에서 만들어지는 컨텍스트에 모든 빈을 다 등록하면 됨 
- 
계층구조를 사용하면서 발생할 수 있는 혼란을 근본적으로 피하고 단순한 설정을 선호한다면 이 방법을 선택할 수 있음 
- 
이때는 서블릿 안에 만들어지는 애플리케이션 컨텍스트가 부모 컨테스트를 갖지 않기 때문에 스스로 루트 컨텍스트 가 됨 
- 
이렇게 만들어지는 서블릿 컨텍스트는 컨텍스트 계층 관점에서 보자면 루트 컨텍스트이지만 웹 애플리케이션 레벨에 두는 공유 가능한 루트 컨텍스트와는 구별됨 
 
- 
루트 애플리케이션 컨텍스트 등록하기
- 
루트 웹 애플리케이션 컨텍스트 는 웹 애플리케이션 레벨에 만들어짐 
- 
만드는 가장 간단한 방법은 서블릿의 이벤트 리스너event listener를 이용하는 것 
- 
스프링은 웹 애플리케이션의 시작과 종료 시 발생하는 이벤트를 처리하는 리스너인 ServletContextListener를 이용- 
스프링은 이것을 구현한 ContextLoaderListener를 제공public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
 
- 
- 
ContextLoaderListener를 이용하는 간단한 방법web.xml파일 안에 아래와 같이 리스너 선언을 넣어주면 됨<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>- 
애플리케이션 컨텍스트 클래스: XmlWebApplicationContext
- 
XML 설정파일 위치(default): /WEB-INF/applicationContext.xml 
 
- 
contextConfigLocation
<context-param>
    <param-nama>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/daoContext.xml
        /WEB-INF/applicationContext.xml
        classpath*:/META-INF/spring/context.xml
        classpath:applicationContext.xml
    </param-value>
</context-param>- 
디폴트 XML 설정파일 위치를 변경하는 컨텍스트 파라미터 
- 
접두어를 붙히지 않으면 웹 어플리케이션의 서블릿 리소스 패스로부터 파일 참조 
- 
클래스패스로부터 설정파일을 찾을 경우 classpath:를 붙혀서 참조 가능
- 
ANT 스타일의 경로표시 방법 이용 가능: /WEB-INF/*Context.xml,/WEB-INF/**/*Context.xml
classpath* vs classpath
- classpath
- 
현재 프로젝트의 classpath만 참조 
- classpath*
- 
현재 프로젝트뿐만 아니라 상위 classloader를 모두 검색하여 참조 
서블릿 애플리케이션 컨텍스트 등록하기
<servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>- 
스프링의 웹 기능을 지원하는 프론트 컨트롤러 서블릿은 DispatcherServlet
- 
web.xml에 등록해서 사용할 수 있는 서블릿
- 
이름을 다르게 지정해주면 하나의 웹 애플리케이션에 여러 개의 DispatcherServlet등록 가능
- 
각 DispatcherServlet은 서블릿이 초기화될 때 자신만의 컨텍스트를 생성하고 초기화함, 동시에 웹 애플리케이션 레벨에 등록된 루트 애플리케이션 컨텍스트를 찾아서 이를 자신의 부모 컨텍스트로 사용
- 
DispatcherServlet의 컨텍스트에 대한 디폴트 설정을 변경하고 싶다면 루트 애플리케이션 컨텍스트와 마찬가지로contextConfigLocation과contextClass를 지정해줄 수 있음
<servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/applicationContext.xml
            /WEB-INF/spring-servlet.xml
        </param-value>
    </init-param>
</servlet>- 
서블릿 컨텍스트의 파라미터 선언 방법은 루트 컨텍스트와 거의 비슷함, <context-param>대신<servlet>안에 있는<init-param>을 이용한다는 점
- 
서블릿 설정파일을 디폴트를 쓰지 않고 여러 개로 분리해야 할 경우 - 
루트 애플리케이션 컨텍스트를 사용하지 않고 모든 계층의 빈을 서블릿 컨텍스트 안에 등록하는 단일 서블릿 컨텍스트 구성 방법을 사용하는 경우 
 
- 
- 
웹 계층 외의 빈을 정의한 applicationContext.xml 과 웹 계층을 위한 spring-servlet.xml 을 서블릿 컨텍스트가 모두 사용하게 하면 리스너를 통한 루트 컨텍스트의 등록은 생량할 수 있음