Framework & Library/Spring & String boot

[Spring] 제어의 역전 - IoC(Inversion of Control)

yjkim_97 2024. 3. 10. 19:32

IoC란?

  • IoC : Inversion of Control (제어의 역전)
  • IoC는 의존성 주입 (DI)로 알려져있다.
  • Spring은 Bean을 생성하고 의존성을 관리하고, 개발자 대신 메모리에서 관리한다.
    개발자가 개발에만 몰두 할 수 있도록 프레임워크가 대신 관리해주는 것이다.

간단하게 요약하자면, Spring이 관리하는 객체를 가져와 사용하는 것을 말한다.

1. IoC Container란?

  • Spring에는 IoC를 담당하는 컨테이너가 있다.
  • Spring이 관리하는 Bean 생성 및 설정방법 등을 다루는 Configuration Metadata가 존재한다.
  • IoC Container를 Spring Container라고도 한다.
  • Spring IoC Container에서 관리되는 객체를 Bean이라고 한다.

IoC Contrainer(스프링 컨테이너)란 Bean을 생성하고 관리한다.  즉, Bean이 생성되고 소멸되기까지의 생명주기를 스프링 컨테이너에서 관리하는 것이다.

 

추가로, 여기서 스프링 컨테이너에서 관리되는 Bean에 대한 종속성을 주입시키는 것을 DI (Dependency Injection) 라고 한다.

2. Bean이란?

앞서 적힌 내용과 같이 Bean이란 스프링 컨테이너가 생성하고 관리하는 객체이다.
아래 코드에서 Car 객체가 해당된다.

@Service
public class TestService {
	@Autowired
    Car car;
}

 

Bean 등록 방법

 

개발자는 스프링 컨테이너에게 해당 객체를 생성해 달라고 요청해야한다. 이 행위를 'Bean을 등록한다.'라고 말한다.

 

그 방법에는 XML 파일 설정, Annotation 추가 등의 여러가지가 있다.

주로 Annotation을 사용하며 대표적인 방법은 아래 코드와 같으며 다양한 어노테이션이 존재한다.

@Component // Car 클래스를 통해 car Bean으로 등록
public class Car {
	...
}

이때 Bean의 이름은 Class명의 첫글자를 소문자로 바꿔 정의된다. (Bean 이름 또한 개발자가 따로 정의해줄수 있다.)

 

 

3. IoC Container 구성

✚ Bean을 관리하는 package 및 interface

Basic packages
* org.springframework.beans
* org.springframework.context
Basic interface
* BeanFactory : 모든 Object 타입을 관리할 수 있는 메커니즘 제공하는 인터페이스이다.
* ApplicationContext : BeanFactory의 하위 인터페이스로 추가 기능을 제공한다.

 

1) BeanFactory

  • org.springframework.beans.factory.BeanFactory
  • IoC Container의 최상위 인터페이스이다.
  • Spring Bean을 관리하고 조회하는 역할을 담당한다.

2) ApplicationContext

  • org.springframework.context.ApplicationContext
  • Spring IoC 컨테이너의 인터페이스로 Bean의 인스턴스화, 구성 및 조립을 담당한다.
  • 아래 추가 기능을 제공한다.
    • Message source 기능을 통한 국제화 처리 (다국어 메시지)
    • 환경변수를 통한 개발 및 운영 환경 분리
    • resource를 파일, 클래스 패스, 외부 등에서 편리하게 조회

3) Configuration Metadata (설정 메타데이터)

  • 설정 메타데이터는 Application에서 Bean 생성 및 사용 방법에 대한 정보를 다룬다.
  • Spring IoC 컨테이너는 설정 메타데이터를 사용한다.
  • 설정 메타데이터는 xml, Java, Groovy 등 다양한 언어로 작성 가능하다.

Configuration Metadata란 간략하게 어떤 객체를 어떻게 사용할 지에 대한 정보를 다룬다.

(주로 나는 Java기반 Annotation으로 설정하고 있다.)

 

@Configuration @Bean @Controller @Service 등의 어노테이션이 달린 클래스가 Spring에 의해 Bean 등록이 되고 관리된다.
이후 @Autowired 어노테이션을 통해 IoC되고 있는 Bean을 가져다가 사용한다.

 

이렇게 Spring에 의해 어떤 객체를 Bean으로 등록할 것인지, 언제 의존성 주입(DI)을 통해 가져다가 사용할 것인지 등의 정보를 Configuration Metadata(설정 메타데이터)라고 한다.

 

❓ @Autowired를 사용하지 않고 Bean를 가져오는 방법은?
ApplicationContext의 getBaen() 메소드를 통해 직접 Spring이 관리하는 Bean을 가져와 사용할 수 있다.

ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
PetStoreService service = context.getBean("petStore", PetStoreService.class);

 

 Configuration Metadata는 어떻게 xml, java, Groovy등 다양한 언어가 가능한걸까?

  • BeanDefinition interface 가 존재한다.
  • Java annotation을 사용한 경우 AnnotationConfigApplicationContext가 AnnotatedBeanDefinitionReader를 통해 Spring이 관리할 Bean 정보들을 읽고 BeanDefination을 생성한다.
  • Xml을 사용한 경우 GenericXmlApplicationContext가 XmlBeanDefinitionReader를 통해 appConfig.xml 설정 정보를 읽고 BeanDefination을 생성한다.
  • 그외 형식들도 마찬가지로 xxxBeanDefinationReader를 통해 BeanDefination을 생성한다.

    이렇듯 해당 언어를 처리 할 수 있는 ApplicationContext가 동작하여 설정 메타데이터를 만든다.

4. IoC 장점

객체간의 결합도를 줄이고 유연한 코드를 작성할 수 있다. 이로 인해 코드의 재사용성이 높아지며, 유지보수가 편리해 진다.
Spring이 Bean을 관리해주기 때문에 개발자는 비즈니스 개발 영역에 좀더 집중 할 수 있다.


Reference

spring framework - The IoC Container

https://steady-coding.tistory.com/600