이클립스 프로젝트에 RoboGuice(RG) 2.0 설치하기

- 안드로이드프로젝트의 libs에 roboguice-2.0.jar, guice-3.0-no_aop.jar, javax.inject-1.jar 파일을 넣고 빌드패스에 추가

- RG 2.0에서는 RoboApplication 상속받은 Application을 작성해서 AndroidManifest.xml에 등록할 필요는 없음

  


Activity 작성

- RoboActivity 상속받은 Activity 작성

- @InjectView , @Inject 등의 어노테이션 사용



모듈 주입 커스터마이징

- AbstractModule 클래스를 상속받는 클래스 작성

- configure() 메소드에서 커스텀 바인딩 정의 : 자세한 구현은 Google Guice 문서 참조

- res/values/roboguice.xml에 아래처럼 컴스텀 모듈 등록


<?xml version="1.0" encoding="utf-8"?>

  <resources> 

    <string-array name="roboguice_modules">

    <item>com.mypackage.MyModule</item>

  </string-array>

</resources>




인스턴스 스코프

RG에 의해 생성 및 관리되어 다른 클래스에 주입되는 클래스의 인스턴스 스코프(생명주기) 설정


1. Singleton 스코프

- 앱에서 하나의 인스턴스만 존재

- 클래스에 @Singleton 어노테이션 선언 : Guice에서 제공

- 어떤 클래스에서 이 객체를 요청하든 동일한 인스턴스가 제공됨. 그러므로 쓰레드세이프하게 작성해야 함.

- Application 컨텍스트는 직접 주입 받을 수있음(특정 Activity, Service 등 current context랑 관계없는 global context)

- current context(액티비티 컨텍스트)를 주입받으려면 Provider<Context>를 사용해야 함

- 싱글턴 스코프를 가진 기본제공 모듈 : Application, ViewListener, Resources 등?

=> 그러나 RG에서 제공하는 대부분의 모듈은 context를 필요로 하므로 ContextSingleton 스코프를 갖는다.

- current context가 필요없거나 또는 Application 컨텍스트만 필요한 클래스에 적합


2. ContextSingleton 스코프

- current context(액티비티 컨텍스트)에 대해서 하나의 인스턴스만 존재

- 클래승 @ContextSingleton 어노테이션 선언 : RG에서 제공하는 스코프

- current context가 필요한 클래스는 ContextSingleton으로 선언

- 동일 액티비티 객체에 대해서 동일 인스턴스 제공(모든 액티비티에 대해서 동일 인스턴스 제공은 아님)

- Application, Context, Activity, Service 등 @Singleton/@ContextSingleton 클래스를 직접 주입받을 수 있음

- 컨텍스트싱글턴 스코프를 가진 기본제공 모듈 : Context, Activity, Service, AssetManager, ContentResolver,

   LayoutInflator 및 기타 시스템서비스 모듈들

- current context가 필요한 클래스에 적합


3. 프로토타입 스코프

- 요청할 때마다 새로운 인스턴스 생성

- 클래스에 별도의 스코프 어노테이션 선언 없음. (프로토타입이란 용어는 제가 스프링에서 따온 것임)

- 주입될 때마다 또는 provider.get() 할 때마다 새 인스턴스가 생성됨

- 스코프가 설정돼있지 않고 public 기본생성자가 존재하는 모든 클래스가 가능

- Handler처럼 Provider에서 get() 요청시마다 새로운 인스턴스를 리턴하는 클래스

- context가 필요없고 상태를 가진 클래스에 적합


스코프 지정 방법

 (1) 구현체 클래스에 @Singleton 붙임

 (2) @Provides 붙은 메소드에 @Singleton 붙임

 (3) bind().xxx().in(Singleton.class);


주요 기본제공 클래스의 스코프

http://code.google.com/p/roboguice/wiki/ProvidedInjections



어떤 컨텍스트를 주입받을 것인가 

- http://code.google.com/p/roboguice/wiki/InjectingContexts

- current context가 필요한게 아니라면 명시적으로 Application을 주입받아라

- Activity가 필요하다면 Activity를 주입받아라

- 잘 모르겠으면 Context를 주입받아라



Inject 되기 위한 생성자 조건

- 기본 생성자가 존재하거나 

- Inject가능한 파라미터로만 구성되고 @Inject 선언된 생성자가 존재


  @Inject

  SomeClass(Context context, MyComponent component) {}

  // 여기서 context와 component는 inject 가능해야함...



일반 POJO 클래스에 다른 객체들을 주입하는 방법

1. POJO 생성을 RG가 처리하는 경우 

- POJO 내부의 @Inject로 선언된 멤버들은 자동 주입됨

- POJO 클래스가 RoboActivity를 상속받는 액티비티의 @Inject 멤버변수로 선언돼있는 경우 등


2. POJO 생성을 RG가 처리하지 않는 경우(개발자 또는 라이브러리에서 직접 생성하는 경우)

- POJO 생성자 등에서 RoboGuice.injectMembers(context, this)를 이용하여 수동으로 주입함



명시적인 injector 사용을 피하는 방법(생성자 등 초기화 메소드를 핸들링할 수 없는 경우)

- 클래스 또는 Provider, ContextScopedProvider를 static하게 inject 받음

- http://code.google.com/p/roboguice/wiki/HowToInjectXYZ

 

 @Inject protected static ContextScopedProvider<T> tProvider; // T는 @ContextSingleton이어야함

 @Inject protected static ExceptionHandler;//singleton


=> 단, MyModule에서 requestStaticInjection(POJO.class)을 해주어야 함

=> 그러나 RG 2.0에서는 static injection을 비권장 ( http://code.google.com/p/roboguice/wiki/UpgradingTo20 )

=> static injection은 context에 액세스할 수 없는 클래스 및 static 메소드를 가진 헬퍼나 유틸 클래스에 적합할 듯.

(http://www.rosscode.com/blog/index.php?title=android-development-part-3-wiring-up-roboguice&more=1&c=1&tb=1&pb=1 )



Provider란 무엇인가

- 인스턴스 생성이 복잡한 경우 인스턴스를 만드는 방법을 제공

- 예를들어 new MyPojo()로 객체 생성후 myPojo.init() 등의 추가 작업한 인스턴스를 리턴

- MyPojo를 주입받는 모듈은 초기화 완료된 MyPojo 인스턴스를 받게 됨

- Module에서 @Provides 어노테이션을 쓰는 메소드를 작성해도 됨(Provider 인터페이스 구현안해도 됨)

- http://code.google.com/p/google-guice/wiki/ProvidesMethods




명시적/묵시적 바인딩

- 명시적 바인딩 : Module에서 bind().to(), bind().toProvider()로 바인딩하는 것

- 묵시적 바인딩 : 

   (1) 기본생성자나 inject가능한 생성자를 가진 구현 클래스가 존재하는 경우

   (2) @ImplementedBy를 통해 기본 구현체를 지정한 경우

   (3) @ProvidedBy를 통해 구현체 인스턴스를 생성해줄 Provider를 지정한 경우



AOP 애스펙트에도 RG의 inject가 가능한가

- 가능함. Aspects.aspectOf()를 통해 aspect 싱글턴을 구하여 Guice 모듈에서 강제 inject시켜줌.



Injection 이후에 지정된 메소드 호출

- Guice의 TypeListener를 이용하거나 GuiceyFruit 또는 MyciaGuice의 @PostConstruct를 사용

- http://stackoverflow.com/questions/2093344/guice-call-init-method-after-instantinating-an-object

- http://code.google.com/p/mycila/wiki/MycilaGuice

- http://code.google.com/p/guiceyfruit/




* 참고

RoboGuice 2.0 설정 방법 : http://code.google.com/p/roboguice/wiki/UpgradingTo20


Posted by 에코지오
,