본문 바로가기
프로그래밍 놀이터/안드로이드, Java

[android] Dagger2 Tutorial

by 돼지왕왕돼지 2018. 12. 4.
반응형

 

@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

 

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

 

 

반응형

댓글0