Dagger2使用

---

##概述

依赖注入(Dependency Injection),简称DI,又叫控制反转(Inversion of Control),简称IOC。Dagger2就是DI框架的一个例子。

---

##作用

将各层的对象以松耦合的方式组织在一起,解耦,各层对象的调用完全面向接口。

---

##提供依赖的两种方式

###使用@Inject注解构造器

```javaclass Thermosiphon implements Pump {private final Heater heater;@InjectThermosiphon(Heater heater) {this.heater = heater;}}```

###使用@Module```java@Moduleclass DripCoffeeModule {@Provides static Heater provideHeater() {return new ElectricHeater();}@Provides static Pump providePump(Thermosiphon pump) {return pump;}}```**使用@Module替代@Inject的情况有:**-依赖是一个接口,不能使用构造器。-依赖是第三方类,不能添加@Inject注解。-依赖在使用前需要被配置。---##注入依赖的两种方式使用@Inject和@Provides注解的类对象组成了一个有向图(graph),该图的顶点(vertex)由它们的依赖参数连接。我们可以通过@Component注解的接口来访问这个有向图。我们将Module传递给@Component的modile参数,Dagger2负责生成一个该接口的实现类,事实上构建一个Component的过程就是在构建一个graph。任何具有默认构造器的Module都不需要显示地设置,builder会自动的创建Module。```javaCoffeeShop coffeeShop = DaggerCoffeeShop.builder().dripCoffeeModule(new DripCoffeeModule()).build();```可简化成:```javaCoffeeShop coffeeShop = DaggerCoffeeShop.builder().build();```如果所需的依赖不需要构造Module就能提供(@Provides方法是静态的),那么实现类会提供一个create()方法来快速的获取一个Component实例。```javaCoffeeShop coffeeShop = DaggerCoffeeShop.create();```Component中可以可以包含两种方法。分别为:-Provision Mothod-Members-injection MethodProvision Method没有参数并且返回需要的类型。Members-injection Method一般没有返回值,参数是需要注入成员变量的类(一般命名为inject)。---##依赖的来源-Module中通过@Provides注解的方法;Component通过@Component.modules直接引用,如果Module中通过@Module,include定义了子Module,也一并包括。-使用@Inject注解构造器的类(没有使用@Scope或者@Scope同Component一致)-该Component依赖的Component的Provision Method-该Component本身-subComponent的未限定builder-以上依赖的Provider或者Lazy包装类。-以上依赖的Lazy包装类的Provider包装类(如Provider)---##单例和作用域Component只会识别未加作用域或者作用域和自己一致的依赖。所以如果@Provids和可注入类加上了作用域,那么Component一定要加上作用域(和@Provide作用域一致的@Scope进行注解)。##Component的dependencies---Component不仅仅可以有modules也可以有dependencies。也就是依赖其他的Component。```java@Component(dependencies = ApplicationComponent.class, modules = ActivityModule.class)@PerActivitypublic interface ActivityComponent {void inject(MainActivity mainActivity);}```注意:只有被依赖的Component中的Provisoin Method才会参与到该Component代表的有向图构建。也就是说只有Provison Method返回的依赖才可以被初始化。---##\#SubComponentComponent可以依赖其他Component,dependence是实现其方式之一,也可以使用SubComponent。却别在于dependence必须明显的显示依赖关系,而SubComponent不必明确的定义依赖关系。举个例子说明一下:```java@Modulepublic class ModuleA {@Providespublic SomeClassA1 provideSomeClassA1() {return new SomeClassA1();}}@Modulepublic class ModuleB {@Providespublic SomeClassB1 provideSomeClassB1(SomeClassA1 someClassA1) {return new SomeClassB1(someClassA1);}}public class SomeClassA1 {public SomeClassA1() {}}public class SomeClassB1 {private SomeClassA1 someClassA1;public SomeClassB1(SomeClassA1 someClassA1) {this.someClassA1 = someClassA1;}}```通过 provideSomeClassB1 可以看出SomeClassB1依赖SomeClassA1先来看一下用dependence的方式实现```javapublic class ComponentDependency {@Component(modules = ModuleA.class)public interface ComponentA {SomeClassA1 someClassA1();}@Component(modules = ModuleB.class, dependencies = ComponentA.class)public interface ComponentB {SomeClassB1 someClassB1();}public static void main(String[] args) {ModuleA moduleA = new ModuleA();ComponentA componentA = DaggerComponentDependency_ComponentA.builder().moduleA(moduleA).build();ModuleB moduleB = new ModuleB();ComponentB componentB = DaggerComponentDependency_ComponentB.builder().moduleB(moduleB).componentA(componentA).build();}}```SomeClassB1依赖SomeClassA1,ComponentB必须明确的定义dependencies,而ComponentA不需要声明ModuleB(modules)。SubComponent实现方式:```javapublic class SubComponent {@Component(modules = {ModuleA.class, ModuleB.class})public interface ComponentA {ComponentB componentB(ModuleB moduleB);}@Subcomponent(modules = ModuleB.class)public interface ComponentB {SomeClassB1 someClassB1();}public static void main(String[] args) {ModuleA moduleA = new ModuleA();ModuleB moduleB = new ModuleB();ComponentA componentA = DaggerSubComponent_ComponentA.builder().moduleA(moduleA).moduleB(moduleB).build();ComponentB componentB = componentA.componentB(moduleB);}}```SomeClassB1依赖SomeClassA1,ComponentB不需要声明依赖,,而ComponentA则需要声明ModuleB(modules),并且ComponentA必须返回@Subcomponent。---##\#可释放的引用使用 Scope 注解时,Component 会间接持有绑定的依赖实例的引用,也就是说实例在 Component 还存活时无法被回收。这时可以用@CanReleaseReferences标记 Scope 注解:```java@Documented@Retention(RUNTIME)@CanReleaseReferences@Scopepublic @interface MyScope {}```然后在 Application 中注入ReleasableReferenceManager对象,在内存不足时调用releaseStrongReferences()方法把 Component 间接持有的强引用变为弱引用。```javapublic class MyApplication extends Application {@Inject@ForReleasableReferences(MyScope.class)ReleasableReferenceManager myScopeReferences;@Overridepublic void onLowMemory() {super.onLowMemory();myScopeReferences.releaseStrongReferences();}...}```这样在内存不足时,DaggerCoffeeShop 间接持有的变 实例为弱引用,如果没有其他对象使用的话就可以被回收。##\#Lazy (延迟注入)有时我们想注入的依赖在使用时再完成初始化,加快加载速度,就可以使用注入Lazy。只有在调用 Lazy的 get() 方法时才会初始化依赖实例注入依赖。```javapublic class Main {@InjectLazy lazyMaker;public void goWork() {...lazyMaker.get(); // lazyMaker.get() 返回 CoffeeMaker 实例...}}```##\#Provider 注入有时候不仅仅是注入单个实例,我们需要多个实例,这时可以使用注入Provider,每次调用它的 get() 方法都会调用到 @Inject 构造函数创建新实例或者 Module 的 provide 方法返回实例。```javapublic class Main {@InjectProvider providerMaker;public void goWork() {...List makerList = new ArrayList(num);for (int i = 0; i < num; i ++) {makerList.add(providerMaker.get());}return makerList;...}}```----##\#限定符(Qualifiers)解决接口或者抽象类不足以描述一个依赖的问题```java@Qualifier@Retention(RetentionPolicy.RUNTIME)public @interface BananaFruit {}``````java@Qualifier@Retention(RetentionPolicy.RUNTIME)public @interface AppleFruit {}```加在所有你想返回确切class的地方。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容