Spring 프레임워크에서 컨테이너는 컨텍스트라고도 합니다. 컨테이너는 Spring 애플리케이션에서 개체의 구성 및 수명 주기를 관리하기 위한 컨텍스트를 제공합니다.
즉, Spring 컨텍스트는 Spring 애플리케이션의 모든 객체(또는 빈)를 보유하고 관리하는 컨테이너입니다. 컨텍스트는 개체의 생성, 초기화 및 연결은 물론 수명 주기 관리를 담당합니다.
Spring 컨텍스트는 XML 파일이나 Java 구성 클래스와 같은 애플리케이션의 개체를 정의하는 구성 파일을 로드하는 역할도 담당합니다. 컨텍스트는 이러한 파일을 읽고 그 안에 정의된 객체를 생성하며 그 과정에서 필요한 종속성을 주입합니다.
전반적으로 "컨테이너"와 "컨텍스트"라는 용어는 Spring 프레임워크에서 Spring Bean이 생성되고 관리되는 환경이라는 동일한 것을 나타내기 위해 종종 같은 의미로 사용됩니다.
Spring Framework(스프링 프레임워크)는 JAVA(자바) 플랫폼을 위한 오픈소스 애플리케이션 프레임워크 중 하나로, 주로 엔터프라이즈급 애플리케이션을 개발할 때 사용됩니다.
스프링 프레임워크의 핵심 기능 중 하나가 Spring Container(스프링 컨테이너)입니다.
스프링 컨테이너는 스프링 프레임워크에서 자바 객체들을 관리하는 공간을 의미하며, 핵심 컴포넌트 입니다.
스프링에서 자바 객체를 Bean(빈) 이라고 하며 스프링 컨테이너는 Bean(빈) 들의 Life Cycle(생명주기)[생성, 관리, 제거]를 관리하며, 생성된 빈에게 추가적인 기능을 제공 하고있습니다.
스프링 컨테이너는 구성 메타데이터1로 표현됩니다. 이를 통해 객체 간 상호 의존성을 표현하게 됩니다.
1 : XML, java 어노테이션, java코드 가 될 수 있다.
Spring Boot(스프링부트)를 사용하기 이전에는 xml을 통해 직접적으로 설정해 주어야 했지만, Spring Boot(스프링부트)의 등장으로 대부분 사용하지 않습니다.
Spring Container(스프링 컨테이너)는 위 그림처럼 구현되어 있습니다.
뭔가 많아 보이실 텐데...저희는 BeanFactory, ApplicationContext 두 인터페이스만 집중하면 됩니다.
BeanFactory는 스프링 컨테이너의 최상위 인터페이스이며, 가장 기본적인 형태입니다.
BeanFactory에서 Bean(빈)을 관리하는 역할을 하며, 컨테이너에서 Bean(빈)을 요청하면 해당 빈을 생성해 제공해 줄 뿐만아니라 Bean(빈)의 생성 시기를 늦추어서 애플리케이션의 부하를 줄이는 등 최적화 기능을 제공하고 있습니다.
빈의 생성과 관계설정 같은 제어를 담당하는 IoC 오브젝트 입니다.
ApplicationContext는 BeanFactory의 확장형 인터페이스이며, BeanFactory가 제공하는 모든 기능뿐만 아니라 여러 인터페이스를 포함합니다.
애플리케이션 컨텍스트는 IoC 방식을 따라 만들어진 일종의 빈 팩토리로 둘 다 동일한 개념이라 생각하면 될 것 같습니다.
주로 사용되는 스프링 컨테이너는 애플리케이션 컨텍스트입니다.
EnvironmentCapable
개발, 운영, 환경변수 등으로 나누어 처리하고, 애플리케이션 구동 시 필요한 정보들을 관리하기 위한 인터페이스
ResourcePatternResolver
파일, 클래스 패스, 외부 등 리소스를 편리하게 조회하기 위한 인터페이스
ApplicationEventPublicher
이벤트 관련 기능을 제공하는 인터페이스
MessageSource
메시지 다국화를 위한 인터페이스
ApplicationContext는 다양한 방식으로 구현될 수 있습니다. XML, JavaConfig, Annotation 등의 방식으로 설정 파일을 작성할 수 있으며, 다양한 환경 설정 파일을 지원합니다. 스프링 프레임워크에서는 ApplicationContext의 구현체로 ClassPathXmlApplicationContext, FileSystemXmlApplicationContext, AnnotationConfigApplicationContext 등이 제공됩니다.
위 그림과 같이 ApplicationContext와 ApplicationContext를 상속하는 WebApplicationContext 2개의 인터페이스가 존재한다.
서비스 계층이나 DAO를 포함한, 웹 환경에 독립적인 빈들을 담아둔다.
서로 다른 서블릿컨텍스트에서 공유해야 하는 빈들을 등록해놓고 사용할 수 있다.
Servlet context에 등록된 빈들을 이용 불가능하고 servlet context와 공통된 빈이 있다면 servlet context 빈이 우선된다.
WebApplication 전체에 사용가능한 DB연결, 로깅 기능들이 이용된다.
DispatcherServlet이 직접 사용하는 컨트롤러를 포함한 웹 관련 빈을 등록하는 데 사용한다.
DispatcherServlet은 독자적인 WebApplicationContext를 가지고 있고, 모두 동일한 Root WebApplicationContext를 공유한다.
ApplicationContext | WebApplicationContext | |
---|---|---|
용도 | 일반적인 스프링 애플리케이션 | 웹 기반 스프링 애플리케이션 |
주요 기능 | DI, AOP, 빈 관리 등 | 웹기능 추가 |
환경 설정 | XML, JavaConfig, Annotation 등 | XML, JavaConfig, Annotation 등 |
웹 관련 기능 | 지원하지 않음 | 웹 애플리케이션 컨텍스트 설정, 웹 환경 관련 기능 지원 |
주요 인터페이스 | ApplicationContext | WebApplicationContext, ConfigurableWebApplicationContext |
서블릿 컨텍스트 지원 | X | 서블릿 컨텍스트 지원, 웹 환경 관련 기능 지원 |
장점 | 다양한 설정방식 지원, 일반적인 스프링 애플리케이션에 적합 | 웹 애플리케이션에 특화된 기능 지원, 서블릿 컨텍스트 설정 가능 |
단점 | 웹 관련 기능 지원하지 않음 | 웹 애플리케이션에 특화된 기능이므로 일반적인 스프링 애플리케이션에 비효율적 |
Spring의 "애플리케이션 컨텍스트"를 Spring이 관리하는 빈을 보관하는 컨테이너로 생각하시면 됩니다. Spring은 다양한 유형의 애플리케이션 컨텍스트 구현을 제공하며 ApplicationContext 인터페이스를 구현하는 모든 객체는 애플리케이션 컨텍스트로 간주될 수 있습니다. 특수 버전인 웹 애플리케이션 컨텍스트는 WebApplicationContext 인터페이스를 추가하여 ApplicationContext 인터페이스를 확장합니다. 이 확장은 서블릿 컨텍스트를 얻을 수 있는 getServletContext() 메서드를 도입합니다.
본질적으로 웹 애플리케이션 컨텍스트는 서블릿 컨텍스트와 일치하도록 설계된 Spring 애플리케이션 컨텍스트의 맞춤형 버전입니다. 이 통합은 getServletContext() 메서드를 추가하여 가능합니다. 또한 이 방법의 도입으로 서블릿 컨텍스트와 밀접하게 연결된 응용 프로그램, 요청 및 세션과 같은 여러 빈 수명 주기 범위도 함께 제공됩니다. 이 상호 작용은 웹 애플리케이션 컨텍스트의 기능과 웹 기반 기능과의 완벽한 통합을 강화합니다.
Child WAC은 여러개가 생성될수있다.
이론적으로 DispatcherServlet는 여러 개 등록될 수 있다. 왜 그래야 하는지는.. 생각해보면 많은 이유가 있겠지만, 아무튼 기술적으로 가능하고 그런 의도를 가지고 설계되었다. 그리고 각각 DispatcherServlet은 독자적인 WAC를 가지고 있고 모두 동일한 Root WAC를 공유한다. 스프링의 AC는 ClassLoader와 비슷하게 자신과 상위 AC에서만 빈을 찾는다. 따라서 같은 레벨의 형제 AC의 빈에는 접근하지 못하고 독립적이다.
추후 서블릿컨텍스트는 따로 포스팅 하겠습니다.
어떤 부분이 좋아서 사용하는지 알아보도록 하자
객체간의 의존성을 관리해줍니다.
객체를 생성하려면 new 생성자를 사용해야 합니다.결과적으로 수많은 개체가 응용 프로그램 내에 존재하게 되고 서로에 대한 참조를 설정합니다. 이러한 상황은 개체 간의 상호 의존성을 증가시킵니다.
이 접근 방식은 상호 의존성을 줄이고 캡슐화를 강화하려는 객체 지향 프로그래밍의 기본 원칙과 크게 다릅니다. 이를 달성하기 위해 Spring 컨테이너가 사용되어 개체 간의 결합이 감소하고 인터페이스에 중점을 둡니다. 반대로 기존 방법을 사용하면 새로운 기능을 도입하여 수동으로 조정해야 합니다. 프로젝트가 확장됨에 따라 종속성 및 후속 코드 수정 사항이 누적됩니다. 반대로 Spring 컨테이너는 구현 클래스에 대한 의존도를 최소화하는 디자인을 용이하게 하여 인터페이스에만 의존하도록 합니다.
Bean(빈)의 라이프사이클을 관리해줍니다.
객체의 초기화, 소멸 등의 작업을 명시적으로 처리 할 필요 없이 스프링 컨테이너가 자동으로 처리하므로
개발자는 Bean(빈)의 초기화와 소멸에 집중하는 대신 핵심 비즈니스 로직에 더 많은 시간과 노력을 투자할 수 있습니다.
AOP(관점 지향 프로그래밍)을 지원합니다.
AOP를 사용하여 로깅, 트랜잭션 관리, 보안 등과 같은 부가적인 기능을 애플리케이션에 적용할 수 있습니다.
의존성 주입을 통해 객체 간의 결합도가 낮아지므로, 단위 테스트나 통합 테스트 등을 쉽게 작성할 수 있습니다.
좋은 그림이있어 가져와봤다.
설정 정보 작성
스프링 컨테이너의 구성 메타데이터를 설정합니다.
구성 메타데이터는 스프링 컨테이너에게 Bean을 생성하고 구성하는 방법을 알려줍니다.
컨테이너 생성
설정정보를 기반으로 스프링 컨테이너를 생성합니다.
Bean 정의 및 생성
구성 메타 데이터 기반으로 Bean을 정의하고 Spring 컨테이너는 이러한 Bean의 인스턴스를 생성합니다.
의존성 주입
bean이 생성되면 Spring 컨테이너는 종속성 주입을 수행하여 bean 간의 관계를 함께 연결합니다.
초기화
Bean이 생성되고 의존성 주입 후 스프링 컨테이너에 의해 Bean의 초기화 작업을 수행합니다.
Bean 사용
초기화 된 후 스프링 컨테이너나 애플리케이션에서 해당 Bean을 사용할 수 있습니다.
소멸
스프링 컨테이너가 종료될때 또는 필요한 경우에 Bean의 소멸 작업을 수행합니다.
https://rainbound.tistory.com/entry/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88
https://devwarriorjungi.tistory.com/entry/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88Spring-Container-%EB%B9%88Bean
https://ittrue.tistory.com/220
https://velog.io/@tank3a/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%99%80-%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B9%88
https://docs.spring.io/spring-framework/reference/core/beans/basics.html
스프링 컨테이너야 고맙다~