책책책/토비의 스프링 3.1

[Spring] 의존관계 주입 (DI: Dependency Injection)

Deveun 2021. 7. 1. 22:48

토비의 스프링 1장: 오브젝트와 의존관계

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

이전게시글에서 살펴본 Ioc방식의 동작원리를 설명하는 용어가 바로 "의존관계주입(DI)"이다.

(이전 게시글 참고:2021.06.05 - [책책책/토비의 스프링 3.1] - [토비] 제어의 역전 (IoC: Inversion of Control))

외부로부터 생성된 오브젝트의 레퍼런스를 제공(주입)받고, 이를 통해 오브젝트간 의존관계가 생성되는 것을 말한다.

이는 의존(종속) 오브젝트 주입이라고도 불리며, 스프링 프레임워크의 차별화되는 특성이다.

 

인터페이스를 통한 느슨한 결합

다음 그림을 예시로 설계 모델 관점에서 의존관계를 설명하면,

Solution 오브젝트는 IfSettingMaker를 통해 ASettingMaker를 사용하기 때문에 인터페이스(IfSettingMaker)에만 의존적이며 구현클래스(ASettingMaker)의 변화에는 영향을 받지 않는다. ==> 구현클래스와의 낮은 결합도

 

 

런타임 의존관계

: 런타임 시에 실제 오브젝트간 의존관계는 모델링 시점과는 다르다. 

이 의존관계는 클래스 모델이나 코드에는 드러나지 않고, 실제 사용하는 오브젝트를 외부(IoC 컨테이너 or 팩토리 등)에서 생성하여 주입해줌으로써 만들어진다. 따라서 이러한 제 3의 존재는 DI 컨테이너라고도 부른다.

(위 예시의 경우, 프로그램이 실행되면 Solution 오브젝트가 실제 사용하는 ASettingMaker가 의존 오브젝트)

==> 오브젝트 생성/선택권한이 외부에 있고, 수동적으로 주입받은 오브젝트를 사용하는 IoC개념과 연결됨!

 

*DL (Dependency Lookup)

: 의존관계 검색으로 불리는 방법으로 자신의 의존 오브젝트를 능동적으로 "찾는다" 라는 점에서 DI와 구분되며, 스프링 ApplicationContext에서 사용되는 getBean() 이라는 메소드가 이에 해당된다.

 

 

DI 응용

 

(1) 기능 구현의 교환

Solution의 세팅값이 로컬환경과 상용환경에서 다르게 설정되어야 한다고 예를 들어보자.

Solution에서 직접 SettingMaker클래스를 생성하면, 환경이 바뀔 때마다 모든 코드에서 생성자 부분을 찾아서 new LocalSettingMaker() <-> ProductionSettingMaker() 를 해줘야한다. 하지만 이를 DI를 사용한다면 아무리 Solution클래스가 많아져도, 다음과 같이 팩토리의 생성코드 부분만 바꿔주면 된다.

 

SolutionFactory.java

@Configuration // 빈 팩토리를 위한 오브젝트 설정 클래스 
public class SolutionFactory { 

    @Bean // 오브젝트를 생성하는 메소드 
    public Solution solution() { 
        return new Solution(settingMaker()); 
    } 
	
    @Bean 
    public IfSettingMaker settingMaker() {
    	// 여기에서만 다르게 생성하면 다른 런타임 오브젝트 의존관계를 가지게 해줌.
    	// return new ASettingMaker();
        // return new LocalSettingMaker();
        return new ProductionSettingMaker();
    } 
}

 

(2) 부가기능 추가

다음과 같은 구조를 적용하여 DI를 받으면, 모든 Solution을 직접 수정하지 않고도 사용하는 SettingMaker의 기능을 계속 추가해나갈 수 있다.

 

(2) 메소드 DI방식

: 지금까지는 생성자를 통해 DI를 했는데, 대신 다음과 같이 메소드를 통해 주입받는것 또한 가능하다.

 

Solution.java

public class Solution {

    private IfSettingMaker settingMaker;
    
    // 생성자
    public Solution(IfSettingMaker settingMaker) {
        this.settingMaker = settingMaker;
    }
    
    // 메소드
    public void setSettingMaker(IfSettingMaker settingMaker) {
        this.settingMaker = settingMaker;
    }
    
    // 생략 ...
}

 

SolutionFactory.java

@Configuration // 빈 팩토리를 위한 오브젝트 설정 클래스 
public class SolutionFactory { 

    @Bean // 오브젝트를 생성하는 메소드 
    public Solution solution() { 
        
        // 생성자DI방식
        // return Solution(settingMaker());
        
        // 메소드DI방식
        Solution solution = new Solution();
        solution.setSettingMaker(settingMaker());
        return solution;
    } 
	
    //생략...
}

 

 

 

[참고서적] http://www.acornpub.co.kr/book/toby-spring3.1-vol1#spring3

 

토비의 스프링 3.1 Vol. 1 스프링의 이해와 원리

스프링의 핵심 프로그래밍 모델의 원리와 이에 적용된 다양한 디자인 패턴, 프로그래밍 기법의 이해를 돕는 책

www.acornpub.co.kr