Dagger2 Scope 注解(例)

Dagger2 中 @Scope 的作用其实很简单:用于保证被标记的 Component 一个实例在注入依赖时, 将标记了同样 Scope 注解的对象只注入同一个对象实例。

@Singleton 只是 Dagger2 预定义的注解。也就是说:如果一个 App 持有多个标记了 @Singleton 的 AppComponent, 这些 AppComponent 注入的对象不能保证是单例。 这也就是为什么需要在 Android 的 Application 类中持有唯一的 AppComponent。

下面是一个使用例:

  • WaterPot 类为 App 的单例工具类。
  • 每一个 Activity 持有自己的 ActivityComponent, 用于提供 Activity 范围内的同一个 VaseTable 实例。
  • 一个 VaseTable 持有多个 Vase , Vase 持有 Flower 和 App 共享单例的 WaterPot。
import dagger.*;

import javax.inject.Inject;
import javax.inject.Scope;
import javax.inject.Singleton;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

class WaterPot {
    private String name;
    public WaterPot(String name) {
        this.name = name;
        System.out.println("[Create] WaterPot : " + name);
    }
    public String water()  {
        return "Water use: " + name;
    }
}

class Flower {
    private String name;
    public Flower(String name) {
        this.name = name;
        System.out.println("[Create] Flower : " + name);
    }
    public String whisper()  {
        return  name + " whisper";
    }
}

class VaseTable {
    public String name;
    public VaseTable(String name) {
        this.name = name;
        System.out.println("[Create] VaseTable : " + name);
    }
}

class Vase {
    private Flower flower;
    private WaterPot waterPot;
    private VaseTable vaseTable;
    @Inject
    public Vase(Flower flower, WaterPot waterPot, VaseTable vaseTable) {
        this.flower = flower;
        this.waterPot = waterPot;
        this.vaseTable = vaseTable;
        System.out.println("[Create] Vase");
    }
    public String check() {
        return "Table: " + vaseTable.name + ":  " + waterPot.water() + " , and " + flower.whisper();
    }
}

@Module
class AppModule {
    static int count = 0;
    @Provides @Singleton static WaterPot provideWaterPot() {
        count ++;
        return new WaterPot("WaterPot-" + count);
    }
}

@Module
class FlowerModule {
    static int count = 0;
    @Provides static Flower provideFlower() {
        count ++;
        return new Flower("Flower-" + String.valueOf(count));
    }
}

@Module
class ActivityRoomModule {
    static int count = 0;
    @Provides @ActivityRoomScope static VaseTable provideVaseTable() {
        count ++;
        return new VaseTable("VaseTable-" + String.valueOf(count));
    }
}

@Scope
@Retention(RetentionPolicy.RUNTIME)
@interface ActivityRoomScope {
}

@Singleton
@Component(modules = {AppModule.class})
interface AppComponent {
    void inject(App app);
    WaterPot waterPot();
}

@ActivityRoomScope
@Component(dependencies = AppComponent.class, modules = {ActivityRoomModule.class, FlowerModule.class})
interface ActivityRoomComponent {
    void inject(ActivityRoom activityRoom);
}

class ActivityRoom {
    @Inject Vase vaseA;
    @Inject Vase vaseB;
    @Inject WaterPot waterPot;
    ActivityRoom() {

        ActivityRoomComponent activityRoomComponent = DaggerActivityRoomComponent.builder().appComponent(App.application.appComponent).build();
        activityRoomComponent.inject(this);
    }
    public void show() {
        System.out.println(vaseA.check());
        System.out.println(vaseB.check());
        System.out.println();
    }
}

public class App {
    public static App application;
    public AppComponent appComponent;

    @Inject WaterPot waterPot;

    App() {
        appComponent = DaggerAppComponent.create();
        appComponent.inject(this);
    }

    public void run() {
        System.out.println("App run..");
        // Room A B share WaterPot
        // Room A B have their own VaseTable 
        ActivityRoom roomA = new ActivityRoom();
        roomA.show();
        ActivityRoom roomB = new ActivityRoom();
        roomB.show();
        System.out.println(waterPot.water());
    }

    public static void main(String[] args) {
        application = new App();
        application.run();
    }
}

输出结果

[Create] WaterPot : WaterPot-1
App run..
[Create] Flower : Flower-1
[Create] VaseTable : VaseTable-1
[Create] Vase
[Create] Flower : Flower-2
[Create] Vase
Table: VaseTable-1:  Water use: WaterPot-1 , and Flower-1 whisper
Table: VaseTable-1:  Water use: WaterPot-1 , and Flower-2 whisper

[Create] Flower : Flower-3
[Create] VaseTable : VaseTable-2
[Create] Vase
[Create] Flower : Flower-4
[Create] Vase
Table: VaseTable-2:  Water use: WaterPot-1 , and Flower-3 whisper
Table: VaseTable-2:  Water use: WaterPot-1 , and Flower-4 whisper

Water use: WaterPot-1
comments powered by Disqus