관리 메뉴

정상에서 IT를 외치다

[Android, Dagger2] DI 기본 개념과 Dagger2 사용 예제 - 놈!놈!놈! 본문

안드로이드

[Android, Dagger2] DI 기본 개념과 Dagger2 사용 예제 - 놈!놈!놈!

Black-Jin 2018. 10. 1. 15:16
728x90
반응형

안드로이드 DI 와 Dagger2 에 관한 포스팅을 해보겠습니다.

설명은 굉장히 짧게! 이해는 아주 잘 되게!



DI 란?


DI 는 Dependency Injection 의 약자로 의존성 주입을 의미합니다. 특정 객체의 인스턴스가 필요한 경우 이를 외부에서 생성하여 전달하는 기법입니다.


Dagger 란?


안드로이드에서 의존성 주입을 구현하기 위해 사용하는 라이브러리 입니다.



사용하는 예제는 '김태호 - 커니의 코틀린' 에서 가져왔습니다.


햄버거 만들기


햄버거(Burger)를 만들어 보겠습니다.

햄버거는 밀빵(WheatBun) 과 소고기 패티(BeefPatty) 로 이루어져 있습니다.


햄버거

public class Burger {

public WheatBun bun;
public BeefPatty patty;

public Burger(WheatBun bun, BeefPatty patty) {
this.bun = bun;
this.patty = patty;
}
}


햄버거를 만들기 위한 밀빵(WheatBun) 과 소고기 패티(BeefPatty) 를 준비해 봤습니다.


밀빵

public class WheatBun {

public String getBun() {
return "밀빵";
}
}

소고기 패티

public class BeefPatty {

public String getPatty() {
return "소고기 패티";
}
}


그러면 우리의 MainActivity 에서 햄버거를 만들려면 어떻게 해야 할까요?

public class MainActivity extends AppCompatActivity {

Burger burger;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

WheatBun bun = new WheatBun();
BeefPatty patty = new BeefPatty();

burger = new Burger(bun, patty);


}

}


이렇게 new 오퍼레이터를 사용해서 밀빵과 소고기 패티를 가져와서 햄버거를 만듭니다.


이렇게 MainActivity 에서 인스턴트를 생성하는게 기존의 방식이었습니다. 여기에 의존성 주입을 사용하면 new 오퍼레이터 사용 없이 외부에서 자동으로 객체를 생성해 줍니다.




Dagger2 적용하기



0. App 버전의 build.gradle 에 라이브러리 추가하기

implementation "com.google.dagger:dagger:$daggerVersion"
implementation "com.google.dagger:dagger-android:$daggerVersion"
implementation "com.google.dagger:dagger-android-support:$daggerVersion"

kapt "com.google.dagger:dagger-android-processor:$daggerVersion"
kapt "com.google.dagger:dagger-compiler:$daggerVersion"

제가 사용한 버전은 2.12 입니다. 대거 최신 버전은 문서를 확인해 주세요.



1. Module 과 Component 를 만들어야 합니다.


Module 은 필요한 객체를 제공하는 역활을 합니다.


우리가 MainActivity 에서 아래와 같이 객체를 생성했죠?

WheatBun bun = new WheatBun();
BeefPatty patty = new BeefPatty();

Burger burger = new Burger(bun, patty);

이걸 Module 이 해줍니다.

@Module
public class BurgerModule {

@Provides
Burger provideBurger(WheatBun bun, BeefPatty patty) {
return new Burger(bun, patty);
}

@Provides
WheatBun provideBun() {
return new WheatBun();
}

@Provides
BeefPatty providePatty() {
return new BeefPatty();
}
}

생성할 객체를 @Provides 어노테이션을 사용해서 생성해 줍니다.


 

Component 는 모듈에서 제공받은 객체를 조합하여 필요한 곳에 주입하는 역활을 합니다.

@Component(modules = BurgerModule.class)
public interface BurgerComponent {

void inject(MainActivity activity);
}

@Componet 어노테이션을 통해 BurgerModule.class 를 가져왔습니다. 이를 inject() 함수를 통해 MainActivity 에 주입했습니다. ( void inject() 의 함수 명은 정해진 값이 아닌 임의의 함수 명을 정해주시면 됩니다. )



2. MainActivity 에서 사용해보기



1번 작업을 한 후 프로젝트를 빌드 해 주시면 Dagger + {ComponetName} 파일이 자동 생성됩니다. 

(여기서는 DaggerBurgerComponent 가 생성됩니다. 이렇게 컴파일 단계에서 의존성을 체크할 수 있어 앱의 안정성을 높여줄 수 있습니다.)

public class MainActivity extends AppCompatActivity {

@Inject
Burger burger;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

/*WheatBun bun = new WheatBun();
BeefPatty patty = new BeefPatty();

burger = new Burger(bun, patty);*/

BurgerComponent component = DaggerBurgerComponent.builder()
.burgerModule(new BurgerModule())
.build();

component.inject(this);

Log.d("MyTag","burger bun : " + burger.bun.getBun() +

" , patty : " + burger.patty.getPatty());

}

}

짜짠! 위와같이 new 오퍼레이터 사용 없이 위와 같은 코드로 burger 객체를 외부에서 생성하여 가져올 수 있습니다.

(burger = new Burger() 를 안했는데도 객체가 생성되었어요!! 놀라워라!!)



이름 그림으로 도식화 하여 이해하기 쉽게 표현해 보겠습니다.


간단히 공급하는 놈(Module)주입받는 놈(Inject) 

그리고 이  사이를 연결해주는 놈(Component)로 이해하시면 됩니다. 놈!놈!놈!




Module

Module 에서 공급할 객체를 생성합니다. (예제에서는 햄거거, 밀빵, 소고기 패티를 생성했습니다.)


Component

Component 에서는 Module을 불러오고 어디로 주입할 지를 정합니다. (MainActivity 주입할 겁니다!)


Inject

@Inject 어노테이션을 통해 주입받는 놈들 가져옵니다. 

(MainActivity 에서 @inject Burger burger 변수를 선언했더니 객체가 두둥! 생성!) 


기존의 객체 생성 방식보다는 코드가 좀 더 많고 복잡해 보이죠? 하지만!! 원리를 알고 사용하다보면 훨씬 좋은 점이 많다고 합니다. (저도 아직 배우는 중이라...아직은 모르겠지만 계속 써볼려고 합니다). 다음 포스팅에서는 이를 안드로이드에서 어떻게 활용하면 좋을지 또 어떤 점이 Dagger2 의 장점인지에 관해 포스팅 해보겠습니다. 그럼 안뇨옹~!


<참고자료>


저는 짧게 설명했지만 DI 와 Dagger2 의 구체적인 개념 설명은 링크1, 링크2에 잘 정리 되어있습니다.

꼭! 읽어 보시길 추천 드립니다.


또 다른 쉬운 예제를 보고 싶다면 쉬운 Dagger2

심화 자료를 원한다면 Dagger2 학습에 필요한 자료


찰스의 안드로이드

Di 기본개념부터 사용법까지

반응형
6 Comments
  • 프로필사진 초코비니 2018.11.12 22:25 신고 좋은 글 잘봤습니다.

    그리고 살짝 뭔가를 클릭했습니다. ^^

    무튼 질문이 있습니다.

    모듈 : 공급하는 놈
    컴포넌트 : 연결하는 놈
    인젝트 : 주입받는 놈

    친절하게 그림을 그려주셔서 이해는 했습니다.
    그런데 application 부분은 어떤 위치에서 무슨 역할을 하는건가요?

    인터넷에서 떠돌아다니는 예제를 보면 볼수록 어려워지네요.

    처음 di 주입이라해서 스프링하고 비슷한건가보네하고 가볍게 봤다가... 이해를 못하고 있습니다.
  • 프로필사진 Black-Jin 2018.11.12 23:13 신고 뭔가를 클릭 해주시다니 역시 배우신 분 :)

    먼저 글 재밌게 읽어 주셔서 감사합니다.

    Application은 앱이 실행될 때 최초 한번 빌드되는 클래스 입니다. Application이 빌드되어야 Activity, Service 등 다른 컴포넌트를 사용할 수 있습니다. 최초 한번 빌드 된다는 특징 때문에 한번 객체를 생성해서 사용할 글로벌 변수를 여기다가 선언 후 전역에서 사용하곤 합니다. 이미지와 함께 잘 설명되어 있는 링크 하나 남기겠습니다 :D

    https://github.com/codepath/android_guides/wiki/Understanding-the-Android-Application-Class
  • 프로필사진 초코비니 2018.11.12 23:48 신고 http://black-jin0427.tistory.com/106?category=727620

    올려주셨던 글과 답변내용을 보고 이해했습니다.

    즐거운 저녁 되시길 바랍니다. ^^
  • 프로필사진 Gradler 2019.03.14 09:24 하나의 모듈을 만들어서 여러곳에 주입하는 경우는 컴포넌트에 inject 메소드를 계속 추가하면 되는건가요?
  • 프로필사진 Black-Jin 2019.03.17 16:30 신고 안녕하세요. 댓글 감사합니다:) 하나의 모듈에서 여러곳에 객체를 주입시키기 위해 서는 모듈의 inject 메소드를 계속 추가해 주어야합니다. 혹은 AndroidInjector 라는 대거의 안드로이드 지원 모듈을 사용할 수도 있습니다. 이와 관련된 포스팅 주소를 남기겠습니다. https://black-jin0427.tistory.com/168
  • 프로필사진 개발고 2022.06.02 11:05 이제야 이해가 가네요 ... 쩔어요 형님
댓글쓰기 폼