1. Dependency Injection 이란?
1.1. Dependency Injection 이 뭐냐?
-
어떤 프로그래밍 언어에든 적용할 수 있는 컨셉이다.
이는 Inversion of Control (control 의 역전)이라고도 불린다.
이 컨셉에 따르면 class 는 dependency 를 정적으로 자신이 결정하는 것이 아니라, 바깥쪽에서 dependency 를 결정해주는 방식이다.
-
public class MyClass{
private final static Logger logger;
public MyClass(Logger logger){
this.logger = logger;
logger.info(“This is a log message.”);
}
}
위 코드의 경우 MyClass 가 스스로 Logger 를 정의하는게 아니라,
바깥에서 주입해주는 Logger 를 사용한다.
-
Dependency Injection(이하 DI)를 통해 test 도 손쉽게 할 수 있다.
mock 을 inject 하기 쉬워지기 떄문이다.
1.2. annotation 으로 dependency 를 표기하자.
-
JSR 330 (Java Specific Request) 에 정의된 dependency 관련 annotation 은 @Inject 와 @Named 가 있다.
-
public class MyPart{
@Inject private Logger logger;
@Inject private DatabaseAccessClass dao;
@Inject
public void createControls(Composite parent){
// do sth..
}
}
1.3. 어디에 inject 를 시켜줄 수 있나?
-
class construction 때 (construction injection), field 에 (field injection), method 의 parameter 에 (method injection) injection 될 수 있다.
-
static 과 non-static fields, method 모두에 DI 할 수 있다.
그러나 static 영역에 inject 하는 것은 좋은 관례가 아니다. 제약사항으로 인해 debug 등이 힘들기 때문이다.
제약사항
static field 는 DI 를 통해 class 의 첫번째 object 가 생성된 후에 inject 될 수 있다. 이 말인즉슨 constructor 에서 static field 에 접근할 수 없다.
static field 는 final 로 mark 될 수 없다.
static method 는 첫번째 class 가 생성된 후에 한번만 불린다.
1.4. class 의 DI 가 되는 순서
-
constructor injection -> field injection -> method injection
-
method 나 field 자체의 @Inject 순서는 JSR330 에 정의되지 않았다.
그러나 보통 정의 순서대로 DI 된다고 생각하면 된다.
2. DI with Dagger2
2.1. Dagger2 가 뭐인고?
-
DI framework 이다.
JSR330 기반이다.
annotation 바탕으로 코드를 생성해낸다.
생성된 코드는 상대적으로 읽고 디버깅하기 쉽다.
-
Dagger2 는 다음 annotation 들을 사용한다.
@Module, @Provides : dependency 를 provide 할 class 와 method 정의
@Inject : dependency 요청. constructor, field, method 모두가 될 수 있다.
@Component : 선택된 module 을 활성화시켜 DI 를 수행한다.
-
Dagger2 는 reflection 을 사용하지 않고, 생성한 코드의 field 접근을 사용한다.
그래서 private fields 에 대한 injection 은 허용되지 않는다.
2.2. dependency provider 정의하기 ( object provider )
-
Dependency injection context 는 일반적으로 inject 될 object set 을 이야기한다.
Dagger2 에서는 @Module 로 annotate 되고, 이것이 inject 될 object 들을 제공한다.
@Module 로 정의된 class 에서는 @Provides 라는 annotation 을 사용해서 제공하는 method 들을 마킹해준다. 이들이 return 하는 것들이 DI 가 된다.
@Provides 의 method parameter 를 이용해서 dependency 에 대한 표현도 할 수 있다.
2.3. dependency 정의하기 ( object consumer )
-
@Inject 를 이용하여 dependency 를 정의할 수 있다.
-
constructor 에 @Inject 로 annotate 된다면, Dagger2 는 이 object 를 dependency 에 활용할 수 있다. 이렇게 함으로써 이 object 들에 대한 @Provides 들을 생략할 수 있다. (constructor injection 은 provider 로서의 역할을 한다.)
2.4. consumer 와 provider 연결하기
-
@Component 는 interface 로 사용되며 이는 Dagger2 가 code 를 생성하는 데 사용된다.
일반적으로 “Dagger” 가 이 interface 의 prefix 로 붙는다.
이를 통해 생성된 class 는 create 라는 method 를 가지며, 주어진 설정에 따라 object 를 설정할 수 있다.
-
@Component interface 는 provider 의 object 들 (module) 과 dependency 를 표현하는 object 를 연결해준다.
-
@Module : @Providers 로 annotate 된 method 들을 가지고 있다.
@Provides : @Module 로 마킹된 class 안에 있으며, DI 에 필요한 object 들을 제공한다.
@Singleton : 제공하는 object 를 singleton 으로 유지한다.
@Component : interface 에서 사용되며, Dagger2 에 의해 dependency 를 수행하기 위한 code 생성에 이용된다.
2.5. Scope annotations
-
@Singleton annotation 으로 provide 되는 object 를 singleton 으로 유지할 수 있다.
2.6. Dagger 에서 field 를 특별히 다루기
-
Dagger2 에서는 field 에 inject 가 자동으로 되지 않는다.
그리고. private field 에 inject 할수도 없다.
field injection 을 받고 싶다면, @Component interface 에 field injection 를 받고 싶은 object 를 param 으로 받는 함수를 정의해야 한다. (예를 들어 MainActivity 에 field injection 을 받고 싶다면, fun inject(mainActivity:MainActivity) 가 정의된 component 가 있어야 한다.)
-
참고자료 : http://www.vogella.com/tutorials/Dagger/article.html
@Component, @Inject, @Module, @Provides, @singleton, annotation 으로 dependency 를 표기, construction injection, consumer 와 provider 연결, create method, Dagger2 annotation, dagger2 reflection, daggerprefix, Dependency injection context, Dependency Injection 이란, dependency provider, DI with Dagger2, di 순서, field injection, field 에 inject, inversion of control, JSR 330, Method Injection, mock inject, object consumer, object provider, private field injection, Scope annotations, static field inject, static inject, static inject restriction, [android] Dagger2 Tutorial
'프로그래밍 놀이터 > 안드로이드, Java' 카테고리의 다른 글
[android] Mockito 맛보기 ( test library ) (2) | 2018.12.07 |
---|---|
[android] Dagger2 tutorial part2 (0) | 2018.12.05 |
[android] Dagger2 for Android Beginners (0) | 2018.12.03 |
[android] Oreo 에서는 Wakelock 이 소용 없다?! (0) | 2018.12.02 |
[android] WakefulBroadcastReceiver 를 알아보자! (2) | 2018.12.01 |
댓글