Spring

[Spring] 스프링 컨테이너 개념 및 동작 원리(DI,IoC,ApplicationContext 개념)

GoodDayDeveloper 2021. 12. 8. 15:10
반응형

여기서는 스프링 컨테이너의 개념 정리와 DI 및 IoC, 스프링 컨테이너의 동작 원리에 대해 설명하고 있습니다.

정리하는 겸, 정보공유하는 겸으로 포스팅하고 있으니 도움이 되셨으면 좋겠습니다~~~

 


 

 

DI(Dependency Injection) : 의존관계, 의존성 주입

 

스프링은 DI로 다형성 + OCP, DIP를 가능하게 지원

(DI 컨테이너 제공)

- 클라이언트 코드의 변경 없이 기능 확장

- 쉽게 부품을 교체하듯이 개발

애플리케이션 실행 시점에 실제 생선된 객체 인스턴스의 참조가 연결되는 것을 의존관계 주입이라고 합니다.

- 의존관계 주입을 사용하면 클라이언트 코드를 변경하지 않고, 클라이언트가 호출하는 대상의 인스턴스를 변경할 수 있습니다.

- 의존관계 주입을 사용하면 정적인 클래스 의존관계를 변경하지 않고, 동적인 객체 인스턴스 의존관계를 쉽게 변경할 수 있습니다. 

예) 의존관계 코드를 손대지 않고  구현코드만 설정해서 동적인 연결을 구현

 

예를 들어

눈길에 가야할 일이 생겼을때, 자동차의 일반타이어를 스노우타이어로 교체하여 

눈길을 무사히 갈수 있게 된다면 스노우타이어만의 교체로 인해 눈길을 갈 수 있게 문제가 해결되게 되겠죠!

 

 

 

 

 

 

제어의 역전 IoC (Inversion of Control)

 

구현 객체가 프로그램의 제어 흐름을 스스로 컨트롤하는 것은 개발자 입장에서는 당연한 자연스러운 흐름이지만

외부에서 관리하는 것을 제어의 역전이라한다.

프레임워크가 내가 작성한 코드를 제어하고, 대신 실행하면 그것은 프레임워크가 맞지만

내가 작성한 코드가 직접 제어의 흐름을 담당하면 그것은 라이브러리!!

한마디로, 스프링 프레임워크가 프로그램을 제어하는 것을 제어의 역전이라 합니다.

 

스프링에서 개발자의 편의를 위해 제공되는 프로그램의 역할을 말하는 거라 생각하시면 됩니다.

 

 

 

 

 

 

컨테이너???

 

IoC or DI 컨테이너 - 의존관계 주입을 대신 객체를 생성하고 관리하면서 의존관계를 연결해주는 것입니다.

(최근에는 IoC가 아닌 DI컨테이너 용어를 자주 사용합니다. 또는 어샘블러, 오브젝트 팩토리 등으로 불려지기도 합니다.)

 

@Configuration : 구성정보를 담당하는것을 설정할때 @Configuration 을 붙여줍니다.

@Bean : 각 메서드에 @Bean을 붙이면 스프링 컨테이너에 자동으로 등록이 됩니다.

ApplicationContext (스프링 컨테이너) :

스프링 컨테이너는 @Configuration이 붙은  클래스를 설정정보로 사용합니다.

여기서 @Bean이 적힌 메서드를 모두 호출해서 반환된 객체를 스프링 컨테이너에 등록합니다.

이렇게 스프링 컨테이너에 등록된 객체를 스프링 빈이라고 합니다.

스프링 빈은 applicationContext.getBean() 메서드를 사용해서 찾을 수 있습니다.

 

 

 

 

 

 

 

스프링 컨테이너란 :

 

ApplicationContext를 스프링 컨테이너라고 합니다.

 

ApplicationContext는 인터페이스입니다.

(구현할때는 new AnnotationConfigApplicationContext(클래스이름.class) 를 사용합니다.)

 

스프링 컨테이너는 XML을 기반으로 만들 수 있고, 에노테이션 기반의 자바 설정 클래스로 만들 수 있습니다.

(편리함으로 보통 자바 기반으로 설정됩니다.)

 

스프링 컨테이너는 파라미터로 넘어온 설정 클래스 정보를 사용해서 스프링 빈을 등록합니다.

예)new AnnotationConfigApplicationContext(스프링.class) 이라 하면 스프링에 있는 @Bean의 메서드를 등록합니다.

 

스프링 빈 조회에서 상속관계가 있을 시에, 부모타입으로 조회하면, 자식 타입도 함께 조회합니다.

그래서 모든 자바 객체의 최고 부모인 object타입으로 조회하면 모든 스프링 빈을 조회합니다.

예) getBean(스프링.class)

 

 

 

 

 

 

BeanFactory vs ApplicationContext

 

BeanFactory < ApplicationContext < AnnotationConfig ApplicationContext

 

BeanFactory

스프링 컨테이너의 최상위 인터페이스입니다.

스프링 빈을 관리하고 조회하는 역할을 담당합니다.

 

ApplicationContext

BeanFactory 기능을 모두 상속받아서 제공합니다.

빈을 관리하고 검색하는 기능을 BeanFactory가 제공해주지만 이외에 부가기능을 제공합니다.

- MessageSource : 메세지소스를 활용한 국제화 기능 (한국어,영어 등)

- EnvironmentCapable : 환경변수 (로컬,개발,운영등을 구분해서 처리)

- ApplicationEventPublisher : 이벤트를 발행하고 구독하는 모델을 편리하게 지원

- ResourceLoader : 파일, 클래스패스, 외부 등 리소스를 편리하게 조회

 

정리

ApplicationContext는 BeanFactory의 기능을 상속 받습니다.

ApplicationContext는 빈 관리기능 + 편리한 부가 기능을 제공합니다.

BeanFactory를 직접 사용하는 일은 거의 없으며, 부가기능이 포함된 ApplicationContext를 사용합니다.

BeanFactory나 ApplicationContext를 스프링 컨테이너라 합니다.

 

 

 

 

 

 

다양한 설정 형식 지원

 

스프링 컨테이너는 다양한 형식의 설정 정보를 받아드릴 수 있게 유연하게 설계되어 있습니다.

(자바코드,XML, Groovy 등)

 

다양한 이유는 BeanDefinition이라는 추상화가 있습니다.

자바나 XML을 읽어서 BeanDefinition을 만들면 됩니다.

BeanDefinition이란 빈 설정 메타정보라 합니다.

자바의 @Bean이나 <bean>의 경우 각각 하나의 메타 정보가 생성이 됩니다.

스프링 컨테이너는 이 메타정보를 기반으로 스프링 빈을 생성합니다.

스프링 컨테이너는 BeanDefinition에 의존합니다.

메타 정보를 기반으로 인스턴스가 생성됩니다.

스프링이 다양한 형태의 설정 정보를 BeanDefinition으로 추상화해서 사용하는 것입니다.

 

 

반응형