[Android] Android 개발에서 Dagger2이용해보기.
Dagger2
url : http://google.github.io/dagger/
요즘 안드로이드 개발에서 Dependency Injection방법을 이용한 개발 방법이 이슈로 자리잡고 있는 듯 합니다. 더군다나 네임드 개발자로 알려진 Jake Wharton 형님이 발표한 자료도 있습니다.
https://speakerdeck.com/jakewharton/dependency-injection-with-dagger-2-devoxx-2014
2라는 숫자가 있는 것을 보면 Dagger1이 있다는 얘기가 됩니다. 처음 Dagger는 Square에서 나왔습니다.
http://square.github.io/dagger/
이 사이트에 가시면 자세한 설명을 보실 수 있어요. 나중에 Dagger에 대한 샘플을 작성해 볼 생각입니다.
Dagger2를 얘기한 이유는 프로젝트가 google github에 있다는 것 때문입니다. 믿고 써보는 google??이라서?
Dagger2에서 중요한 Annotation은 @Module, @Provides, @Component, @Inject 정도 일 것 같습니다.
@Module : Module로 구성되고, 내부에서 주입될 객체들을 provide해주는 것.
@Provides : 객체 주입에 필요한 내용을 리턴해주는것
@Component : Module과 Inject간의 Bridge같은 역활.
@Inject : 객체의 주입.
대충 이런정도의 설명... 저는 참 설명을 못하네요 ㅡ.ㅡ
Dagger2를 이용하기 위한 전반적인 순서 입니다.
gradle 스크립트에 아래와 같은 내용을 추가 해 줍니다.
apply plugin: 'com.neenbedankt.android-apt' buildscript { repositories { mavenCentral() } dependencies { classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4' } } android { ........ dependencies { ....... provided 'javax.annotation:jsr250-api:1.0' apt 'com.google.dagger:dagger-compiler:2.0' compile 'com.google.dagger:dagger:2.0' } }
그리고 사용할 모델들을 정의 해 줍니다. 저는 아래와 같은 예제를 만들어 보았습니다.
Motor.java
public class Motor { private int speed; public Motor() { this.speed = 0; } public int getSpeed() { return speed; } public void accelerate(int value) { speed = speed + value; } public void setSpeed(int value) { speed = value; } public void brake() { speed = 0; } }
Bike.java
public class Bike { private Motor motor; public Bike(@NonNull Motor motor) { this.motor = motor; } public void increaseSpped() { this.motor.setSpeed(this.motor.getSpeed() + 1); } public void decreaseSpeed() { if (this.motor.getSpeed() > 0) { this.motor.setSpeed(this.motor.getSpeed() - 1); } } public int getSpeed() { return this.motor.getSpeed(); } }
그리고 Module을 정의 합니다.
우선 MotorModule.java 입니다. 이건 단순히 Motor객체를 제공해 주는 역활만 합니다.
@Module public class MotorModule { @Provides Motor provideMotor() { return new Motor(); } }
BikeModule.java입니다.
@Module( includes = MotorModule.class ) public class BikeModule { @Provides Bike provideBike(Motor motor) { return new Bike(motor); } }
여기서 보면 Bike객체를 제공해주는 @Provides을 보면 Motor객체가 파라미터로 존재합니다. 과연 이 파라미터는 어디서 제공받고 있을까 라는 의문이 듭니다. 이건 @Module의 includes부분에 보면 MotorModule.class를 포함하고 있고, MotorModule에서 Motor객체를 provides하고 있기에 가능합니다.
이렇게 되면 BikeModule안에서 Motor객체를 필요로 하는 곳에서는 모두 파라미터로 정의하면 Motor객체를 제공받을 수 있습니다.
그리고 Provides된 것을 Inject 하여 사용할 수 있는데 Bike객체를 Inject하여 사용해 볼까 합니다.
그럼 Bike는 어디에서 사용할 까요? 위에서 중요 Annotation중에 @Component를 알려드렸습니다. Module과 Inject간의 Brige같은 역활을 한다고 했는데 사용할 Component는 아래와 같습니다.
MainActivityComponent.java
@Component( ... modules = { ... BikeModule.class } ) public interface MainActivityComponent extends ActivityComponent { void inject(@NonNull MainActivity mainActivity); }
이와 같이 Component를 정의했습니다.
이렇게 Component를 정의하고 컴파일 하면 "DaggerMainActivityComponent가" 만들어 집니다. 이걸 가지고 실질적으로 객체 주입을 진행할 수 있죠.
DaggerMainActivityComponent.builder() ... .bikeModule(new BikeModule()) .build();
이와 같이 하면 사용할 Component에 대해서는 준비가 끝납니다. 그럼 객체 주입은 어떻게 할까요? 몇가지 방법이 있지만 저는 객체에 @Inject anootation방법을 이용해서 사용 할려고 준비했습니다.
@Inject Bike bike;
이와 같이 하여 Bike객체 사용에 대한 준비를 합니다.
이건 component에서 inejct라는 메소드를 정의해서 상용할 수 있는 부분입니다 그럼 inject라는 것을 하지 않고 사용할 방법은 있을까요? Component에서 getBike()라는 메소드를 만들어서 사용할 방법도 있긴 합니다.
이 예제에 대한 소스는
https://github.com/drcarter/Dagger2Example
에 올려둿습니다..
저도 Dagger2에 대해서 공부하고 정리하다 보니 설명이 명확하진 않은 듯 합니다.
오히려 맨 위에 Jake Wharton형님이 pt로 설명한 내용이 더 좋을지도요 ㅎㅎㅎ
'Android' 카테고리의 다른 글
Guava: Google Core Libraries for Java 간단한 사용방법. (0) | 2015.11.06 |
---|---|
[Android] MVC, MVVM, MVP (0) | 2015.10.26 |
[Android] Fragment에서 onActivityResult 결과 받기. (1) | 2015.10.02 |
[Android] Hexagon Image 만들기. (0) | 2014.12.23 |
underline textview (0) | 2014.11.19 |