Dagger2를 알아보자 – 기본편
Dagger2를 알아보자 – Scope 
Dagger2를 알아보자 – Injection의 종류 (You’re here)
Dagger2를 알아보자 – Qualifier 
Dagger2를 알아보자 – Binding 
Dagger2를 알아보자 – Multibinding
Dagger2를 알아보자 – SubComponent
Dagger2를 알아보자 – Android
Dagger2를 알아보자 – Testing(준비중)
Dagger2를 알아보자 – Dynamic Feature에 적용하기(준비중)


인젝션의 종류(Direct vs Lazy vs Provider)

@Module
public class CounterModule {
 
    int next = 100;

    @Provides Integer provideInteger() {
        System.out.println("computing...");
        return next++;
    }
}

인젝션의 종류에 대한 차이점은 위의 모듈을 통해 설명하겠습니다.

Direct injection

public class DirectCounter {

    @Inject Integer value;

    public void print() {
        System.out.println("printing...");
        System.out.println(value);
        System.out.println(value);
        System.out.println(value);
    }
}

일반적인 인젝션인 경우입니다. 한번 주입받은 객체는 여러번 참조해도 처음 주입받은 같은 객체입니다.

결과:
computing…
printing…
100
100
100

Lazy injection

객체가 초기화하는데 시간이 필요하다면 Lazy 인젝션을 고려해볼수 있습니다. 바인딩 될 타입을 위해 Lazy<타입>을 만들어 주기만 하면됩니다. Lazy<타입> 객체의 get() 메소드를 호출 해주기 전까지는 객체가 초기화 되는것을 늦출 수 있습니다. Lazy 타입의 객체도 같은 그래프 내에서 싱글톤으로 관리 가능합니다.

public static class LazyCounter {

    @Inject Lazy<Integer> lazy;

    public void print() {
        System.out.println("printing...");
        System.out.println(lazy.get());
        System.out.println(lazy.get());
        System.out.println(lazy.get());
    }
}

get()메소드를 통해 얻은 객체 또한 초기화만 늦출뿐 매번 호출해도 같은 객체입니다. 그러므로 결과는 아래와 같습니다.

결과:
printing…
computing…
100
100
100

Provider injection

@Inject된 Provider에대해 get()이 호출될때마다 새로운 인스턴스가 만들어 집니다. 하나의 Provider 객체로 여러 인스턴스가 반환될 수 있습니다. 몇개의 옵션 (팩토리, 빌더 등)을 가지고있는 동안, T 대신에 Provider <T>를 주입하는 옵션이 있습니다. @Inject생성자에 대해서는 새로운 인스턴스를 만들지만, @Provides메소드에 대해서는 보장하지 않습니다.

대개의 경우 Provider를 사용하는것은 그래프내에서 잘못된 Scope나 설계패턴을 만들어낼 수 있습니다. 그래도 드물게 필요한 경우가 있으니 알아두시면 좋습니다. 

public class ProviderCounter {

    @Inject Provider provider;

    public void print() {
        System.out.println("printing...");
        System.out.println(provider.get());
        System.out.println(provider.get());
        System.out.println(provider.get());
    }
}

Provider로부터 get()을 호출하면 매번 새로운 객체를 생성하게 되어 다음과 같은 결과를 보입니다.

결과:
printing…
computing…
100
computing…
101
computing…
102

Buy me a coffeeBuy me a coffee

6개의 댓글

Jae · 2020년 5월 26일 6:08 오전

정리된 설명 잘 보고 있습니다. Dagger2를 복습 및 정리하는데 많은 도움이 됩니다.
그런데, ‘Lazy injection’ 예제 결과에서 ‘printing…’ 이 ‘computing…’ 보다 번저 나와야 할 듯 합니다.

    Charlezz · 2020년 5월 26일 11:30 오전

    수정했습니다. 알려주셔서 감사합니다 🙂

park · 2020년 7월 9일 2:25 오후

설명 감사드립니다~!
다만.. 궁금한 부분이있는데 provideInteger에서 next를 ++하고 반환하는거면
direct, laze 전부 101로 나와야하는게 아닌가요? 너무 기초적인 부분인 것 같은데 dagger가 생소해서 질문드립니다..

    Charlezz · 2020년 7월 10일 7:41 오전

    Dagger와 관계없이, 자바 프로그래밍 언어 측면에서 보았을 때 모듈에서 후위 증감 연산자를 사용하고 있기 때문에 100을 반환하는게 맞는 것 같습니다. 전위 증감 연산자를 사용하는 경우 말씀하신대로 101을 반환할 것 입니다.

      paark · 2020년 7월 10일 1:25 오후

      모자란 질문에 친절한 설명 감사드립니다!

        Charlezz · 2020년 7월 10일 7:46 오후

        감사합니다 🙂

답글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.