Container
이란 개발자가 작성한 코드를 처리하는 독립적인 존재이다. Container은 인스턴스의 생명주기를 관리하며, 생성된 인스턴스들에게 추가적인 기능을 제공해준다.
인스턴스의 생명주기란?? Container 스스로 작성한 코드를 참조한 뒤 알아서 객체의 생성과 소멸을 컨트롤한다.
🔍 인스턴스
- 객체와 인스턴스는 크게 차이를 보이지 않는다. 객체는 모든 인스턴스를 포괄하는 넓은 의미를 가지고, 인스턴스는 해당 객체가 어떤 클래스로부터 생성된 것인지를 강조한다.
- 일반적으로 실행 중인 임의의 프로세스, 해당 클래스의 구조로 컴퓨터 저장공간에서 할당되어 현재 생성된 객체를 의미
🔍 Lifr Cycle Callback (생명 주기)
- Spring IOC Container가 IOC Container을 만들고 그 안에 Bean을 등록할 때 사용하는 인터페이스를
Life Cycle Callback
이라고 함- 여기에는
@Component
이 붙어있는 모든 클래스의 인스턴스를 생성해 Bean으로 등록하는 작업을 수행하는 어노테이션 프로세스가 등록되어 있다.
Spring에는 Spring Container
과 IOC Container
이란 개념을 사용한다.
Spring Container
는 Spring Framework
의 핵심부에 위치하며, 종속 객체 주입을 이용하여 Application을 구성하는 Component들을 관리한다. 이 떄, Spring Container에서 생성되는 객체를 Bean
이라고 한다.
Bean
은 Spring IOC Container
가 관리하는 자바 객체를 말한다.
Bean은 Spring IOC Container에 의해 인스턴스화, 관리, 생성된다.
이 Bean은 Singleton
으로 존재한다.
🔍 Singleton
- 동일한 요청이 각기 다른 클라이언트에게 동시에 들어오는데, 각각 객체를 상이한 메모리 공간에 할당시켜 응답해주면 메모리 공간이 남지 않게 된다.
- 위 문제를 해결하기 위해, 동일한 요청에 대해서는
Singleton
패턴을 적용시킨다.- Singleton 패턴
- 이 패턴은 클래스의 인스턴스가 1개만 생성되는 것을 보장하는 디자인 패턴이다.
- 이 인스턴스에 대해서
Static
을 통해 최소 1번만 메모리를 할당시키며 이후 해당 인스턴스 호출이 생길 때마다 최초로 생긴 인스턴스를 사용한다.
IOC Container
는 이러한 객체(Bean)을 인스턴스화하고 구성하며 라이프사이클동안 관리한다.
🔍 Bean 정의 방법
Bean은 @Component
, @Service
, @Repository
, @Controller
어노테이션으로 주석이 달린 Java 객체이거나 XML
(설정 메타 테이터) 구성 파일에서 정의된다.
클래스를 이러한 스테레오타입(@Component
, @Service
, @Repository
, @Controller
) 중 하나로 주석 처리하면 Spring Boot는 애플리케이션 시작 중에 이러한 클래스를 자동으로 감지하고 등록한다.
@Bean
어노테이션 메서드를 사용하여 설정 클래스에서 명시적으로 Bean을 정의할 수 있다.
new
로 생성하는 객체는 Bean이 아니고, ApplicationContext.getBean()
으로 얻어지는 객체가 Bean이다. 즉, ApplicationContext
가 만들어서 그 안에 담고 있는 객체이다.
✅ Bean 장점
Spring IOC Container에 Bean이 등록되면 다른 Bean이나 구성 요소에 주입하여 느슨한 결합을 가능케 하고 모듈화된, 재사용 가능한 코드를 촉진할 수 있다. (DI 장점?)
Spring boot의 Bean은 애플리케이션 내에서 다양한 구성 요소의 라이프사이클과 의존성을 관리함으로써 모듈화된, 유지보수가 용이하고 유연한 애플리케이션을 만들어준다.
Bean Scope
는 Spring Framework에서 Bean 객체의 생명주기와 범위를 정의하는데 사용된다. 스코프는 Bean 객체가 생성되고, 존재하고, 소멸하는 방식을 결정
스코프는 다른 생명주기를 가지며, 필요에 따라 적절한 스코프를 선택하여 Bean을 정의한다. @Scope
어노테이션을 사용하여 설정하거나 XML 설정에서 정의
기본 스코프이며, Spring IOC Container 내에서 한 개의 인스턴스만 생성되고 관리된다. 애플리케이션 전반에 걸쳐 동일한 Bean 인스턴스가 공유
Bean을 요청할 때마다, 새로운 인스턴스가 생성. 각 요청에 대해 새로운 인스턴스가 반환
웹 애플리케이션에서 HTTP 요청마다 생성되는 스코프. 각 HTTP 요청에 대해 새로운 인스턴스가 생성되며, 요청이 완료되면 소멸
웹 애플리케이션에서 세션마다 생성되는 스코프. 각 세션에 대해 새로운 인스턴스가 생성되며, 세션이 종료되면 소멸
웹 애플리케이션에서 애플리케이션마다 생성되는 스코프. 각 애플리케이션에 대해 새로운 인스턴스가 생성되며, 애플리케이션이 종료되면 소멸
웹 소켓 연결마다 생성되는 스코프. 각 웹 소켓 연결에 대해 새로운 인스턴스가 생성되며, 연결이 종료되면 인스턴스가 소멸
🔍 Component Scanning
애플리케이션의 클래스 경로에서 컴포넌트를 찾아서 자동으로 등록하는 매커니즘
Spring IOC Container가 애플리케이션에 정의된 모든 @Component
, @Service
, @Repository
,@Controller
, @Configuration
어노테이션이 붙은 클래스를 자동으로 찾고 Bean으로 등록한다.
--> 위 어노테이션(스테레오타입 어노테이션)은 @Component
가 부여된 클래스이다.즉, Component Scan은 @Component
가 붙어있는 클래스를 대상으로 한다.
@SpringBootApplication
어노테이션이 붙은 클래스의 패키지와 그 하위 패키지를 대상으로 Component Scanning이 이루어진다. 이렇게 하면 해당 패키지 내의 모든 컴포넌트가 자동으로 찾아지고 Bean으로 등록된다.
특정 패키지에서만 수행하도록 지정하려면 @ComponentScan
어노테이션을 사용하여 명시적으로 범위를 지정 가능
✅ Component Scan 장점
XML 설정 파일이나 Java Config 클래스에서 수동으로 Bean을 정의하는 것보다 편리하며, 애플리케이션 확장성과 유지 보수성을 높여준다.
클래스를 자동으로 등록하기 때문에 개발자는 적은 양의 설정 코드를 작성해도 되어 개발 생산성이 향상된다.
@Configuration
은 클래스에 붙이면 해당 클래스가 Spring의 설정 클래스임을 나타냄. 이 설정 클래스는 주로 Bean 정의와 Bean 간의 의존성을 설정하는데 사용된다.
@Configuration
이 붙은 클래스 내부에는 @Bean
어노테이션을 사용하여 빈을 정의할 수 있다. 이 Bean들은 Spring IOC Container에 의해 관리되며 필요한 경우 다른 Bean으로 주입 가능하다.
@Configuration
을 통해 애플리케이션의 구성 요소를 명시적으로 저의하고 관리 가능하다. 또한 외부 구성 요소와의 통합 및 설정을 용이하게 함
ex) 데이터베이스 연결, 외부 API 키 설정 등과 같이 애플리케이션의 설정을 정의하고 관리하는데 사용 할 수 있다.
✅ Configuration 장점
@Configuration
을 사용하여 애플리케이션간의 유연성과 확장성을 높일 수 있다.@Configuration
public class MyConfiguration {
@Bean
public MyBean myBean() {
return new MyBean;
}
}
@Configuration
어노테이션이 붙은 MyConfiguration
클래스가 Spring 설정 클래스임을 나타낸다.
@Bean
어노테이션이 사용된 메서드는 myBean()
이라는 이름의 Bean을 정의
Spring IOC Container는 이 클래스를 검색하여 MyBean
객체를 Bean으로 등록하고, 이 Bean은 다른 Spring 구성 요소에서 주입될 수 있다.