컴퓨터/WEB

[Spring] DI(Dependency Injection)와 IoC(Inversion of Control)란?

정석이 2022. 10. 23. 23:53

 

DI(Dependency Injection)

DI는 유연하게 확장 가능한 객체를 만들어 두고 객체 간의 의존 관계는 외부에서 설정하는 것이다.

 

 

의존관계?

- A 클래스에서 B 클래스의 객체를 멤버 변수로 갖고 있거나, B 클래스 객체의 메소드를 호출하는 관계일 때 "A 클래스가 B 클래스에 의존한다" 라고 한다.

 

class B{
	String name;
  	
    public String call(){
    	return this.name + "입니다.";
    }
}

class A{
	B b = new B(); // B 클래스의 객체를 멤버 변수로 갖는다.
    
    b.name = "농부";
    
    String callB = b.call(); // 객체의 메소드를 호출
}

// A 클래스가 B 클래스에 의존한다.

 

 

이 때 DI는 의존하는 객체를 할당해주는 것이라고 할 수 있다.

 

객체를 생성하는 코드를 없애주고 자동적으로 객체 인스턴스를 할당해주는 것이다.

 

스프링은 설정 파일이나 annotation을 통해 객체 간의 의존 관계를 설정할 수 있다. 직접 생성 안해도 됨

 

 

 

IoC (Inversion of Control - 제어의 흐름을 바꾼다)

 

IoC는 메소드나 객체의 호출 작업을 개발자가 결정하는 것이 아니라, 외부에서 결정하는 것을 의미한다.

 

 

객체의 의존성을 역전시켜 객체 간의 결합도를 줄이고 유연한 코드 작성을 도와 유지 보수를 편하게 할 수 있게 하였다.

 

 

기본에 개발자가 객체의 생성 등 관리 작업까지 도맡았을 때에는 객체 생성, 의존성 객체 주입, 메소드 호출의 순서였다면

 

 

스프링을 사용함으로써 객체 생성, 스프링이 객체 주입해줌, 그 메소드 호출해서 사용 순으로 바뀌게 된 것이다.

 

그러니까 제어의 흐름을 개발자가 아니라 스프링에게 맡긴다는 의미이다.

 

이러한 IoC의 구현 방법 중 하나가 DI 이다.

 

 

 

Bean

bean은 spring IoC 컨테이너가 관리하는 자바 객체이다.

 

 

 

우리가 알던 기존의 자바 프로그래밍에서는 class를 생성하고 new를 입력하여 원하는 객체를 직접 생성한 후에 사용했다.

 

하지만 spring에서는 직접 생성 안해도 됨

 

이렇게 spring에 의해 생성되고 관리되는 자바 객체를 Bean이라고 하는 것이다.

 

DI(의존성 주입)는 스프링 컨테이너가 해주는 일이므로 어떤 객체를 주입해줘야 하는지 정보가 필요하잖음

 

그래서 Bean을 등록해서 스프링 컨테이너에서 관리할 자바 객체를 등록해주는 역할을 하는거임

 

 

 

이 빈들의 생명주기(Life Cycle)를 관리하는 의미는 Bean-Factory 라고 한다.

 

Bean-Factory에 여러가지 컨테이너 기능을 추가해 ApplicationContext라고 함

 

 

 

Bean Factory

- Bean을 등록, 생성, 조회, 반환 관리

- 일반적으로 BeanFactory 보다는 이를 확장한 ApplicationContext를 사용함

- getBean() method가 정의되어 있음

 

 

ApplicationContext

- BeanFactory를 확장한 IoC 컨테이너

- Bean을 등록, 생성, 조회, 반환을 관리한다는 점은 BeanFactory와 같다.

- Spring의 각종 부가 서비스를 추가로 제공하여 ApplicationContext 구현 클래스는 여러 종류가 있다.

  ex) StaticApplicationContext

 

 

BeanFactory라고 부를 때에는 주로 빈의 생성과 제어의 관점,

ApplicationContext라고 할 때에는 스프링이 제공하는 애플리케이션 지원 기능을 모두 포함해서 얘기한다는 느낌이다.

 

 

 

Bean 생성 범위

- 싱글톤 빈

 

스프링 빈은 기본적으로 싱글톤으로 만들어진다.

 

그러면 컨테이너가 제공하는 빈의 인스턴스는 항상 동일하겠지?

 

-> 컨테이너가 항상 새로운 인스턴스를 반환하게 만들고 싶다면 scope를 prototype으로 해주면 된다.

 

 

xml configuration file

<bean id="memberService" class="com.test.농부.service.MemberServiceImpl" scope="prototype"/>

 

범위 설명
singleton 스프링 컨테이너당 하나의 인스턴스 빈만 생성 (default)
prototype 컨테이너에 빈을 요청할 때마다 새로운 인스턴스 생성
request HTTP request별로 새로운 인스턴스 생성
session HTTP session별로 새로운 인스턴스 생성