[Spring] 의존성 주입(Dependency Injection, DI)과 IoC

jinni·2022년 12월 4일
0

Spring

목록 보기
3/4

DI란?

어떤 객체가 사용하기 위한 객체를 직접 생성하는 것이 아니라, 외부로부터 주입을 받아 사용하는 것을 말한다.

인젝션 방식은 몇 가지 더 있지만, 해당 글은 생성자 주입을 바탕으로 작성.

🤔 왜 DI로 코드를 작성하는데?

여기서 우리는 결합의 관점에서 설명할 수 있다.

결합은 강해질 수도 느슨해질 수도 있다.

아래 코드를 보면서 확인해보자!

public class Controller {
	private final Service service;
    
    public controller() {
    	this.service = new Service();
    }
}

public class Service {
	private final Repository repository;
    
    public Service() {
    	this.repository = new repository();
    }
}

public class Repository { ... }

기본 생성자를 통해 new 연산자로 초기화해서 사용하는 모습을 알 수 있다. 근데, Repository에서 생성자를 생성할 때, 매개변수가 존재하는 생성자로 변경한다면, 어떻게 될까?
(Repo -> 설명하기 위해 class로 만들어서 설명함.)

예시에 나와 있는 모든 코드를 수정하는 일이 발생한다. 이는 객체 간의 관계가 아니라 클래스 간의 관계가 맺어지는 것이기 때문이다. 이를 강한 결합이라고 한다. 그리고 우리는 객체지향적 프로그래밍을 해야 하기 때문에 객체 간의 관계를 맺어주는 것이 중요하다!

그럼, 강한 결합을 해결하는 방법은 없어? 😯

생성자의 파라미터에 내가 사용할 클래스의 객체를 주입 받는 방식을 사용하면 된다.

예를 들어,

public class Controller {
	private final Service service;
    
    public Controller(Service service) {
    	this.service = service;
    }

위와 같이 말이다 !

이렇게 생성자 주입을 통해 사용하게 되면, 처음 예시보다 결합을 상대적으로 느슨하게 할 수 있다. 스프링에서는 어플리케이션이 실행될 때, 스프링 컨테이너에 등록된 Bean을 통해서 객체를 연결해준다. 그럼, "객체를 계속 생성해줄 수도 있는 거 아니야?" 물어볼 수 있겠지만, Bean은 하나의 객체만 생성해서 전부 공유하는 싱글톤으로 되어 있다.
(스프링 컨테이너는 Bean을 관리하는 통이라고 생각하면 된다.)

이런 방식으로 작동이 된다면, 우리는 우리가 직접 객체를 생성하는 것이 아니라, Bean을 통해 외부로 부터 객체를 입력 받게 되는 것이다. 이를제어의 역전(Inversion of Control)이라고 한다.

DI를 사용하면 무슨 장점이 있는데?

  • 두 객체 간의 관계라는 관심사의 분리
  • 두 객체 간의 결합도를 낮춤
  • 객체의 유연성을 높임
  • 테스트 작성 용이
  • lombok 라이브러리 활용으로 인한 코드 간결함
  • 객체의 불변성 확보 (하나의 공유되는 객체를 바라보면서 진행되어야 하는데, 서로 다른 객체를 바라보면 큰일나기 때문)

여기서 lombok 라이브러리 활용은 해당 라이브러리에 있는 생성자 어노테이션을 함께 활용할 수 있다는 것이다. 그럼, 생성자 작성 코드를 날릴 수 있어서 코드가 간결해지는 효과가..!!

코드는 바로 위에 코드에서 수정하는 방식으로 예를 들겠음.

@RequiredArgsConstructor
public class Controller {

	private final Service service;
 
	...

이런 식으로 코드가 한결 깔끔해지는 것을 알 수 있다..!

참고
https://cheershennah.tistory.com/227
https://mangkyu.tistory.com/150

profile
조금씩 천천히 꾸준하게

0개의 댓글