Dagger学习 -- 基础概念

目标

了解 Dagger 基本概念

官方定义

Google 对 Dagger 的定义如下:

Dagger is a fully static, compile-time dependency injection framework for both Java and Android. It is an adaptation of an earlier version created by Square and now maintained by Google.

Dagger 是一个为 Java 和 Android 设计的完全静态,编译时依赖注入框架。现在由 Google 维护,它对 Square 开发的早期版本进行了改写。

什么是编译时依赖呢?就是不在运行时依赖,额...Dagger 会通过注解,生成代码,而这个代码跟我们手动写的依赖注入的代码一样。

如果你对『依赖注入』不了解,请看[这篇文章]()(未填的坑)。

Dagger1.x已经废弃,我们以后所说的Dagger就是Dagger2.x。

Dagger 原理

Dagger 使用了注解,我们先来最基本的注解的用法。

声明依赖 @Inject

Dagger 使用注解 javax.inject.Inject 来修饰一个类的构造函数,然后就 Dagger 就可以管理它了。当 Dagger 需要 该类的实例时,就会调用这个构造函数来构造它,也会自动实例化该构造函数的参数所需要的实例。

@Inject 也可以修饰一个类的属性,在构造这个类时,Dagger 会将这个属性所需要的对象实例化出来。但是要注意,这个属性的类型构造函数需要注入即也用 @Inject 修饰。

@Inject 还可以修饰一个方法,这样在构造实例后,会立刻调用该方法。并不推荐这样做,因为这就是初始化的工作嘛,都可以在构造函数里做。

class Thermosiphon implements Pump {
  private final Heater heater;

  @Inject
  Thermosiphon(Heater heater) {
    this.heater = heater;
  }

  ...
}

class CoffeeMaker {
  @Inject Heater heater;
  @Inject Pump pump;

  ...
}

但是 @Inject 有他的局限性

  1. 接口不能注入,它没有构造函数。而一个好的设计是面向接口编程
  2. 第三方类库的类,我们不能修改,没法给它加 @Inject
  3. 我们需要的对象可能需要配置,而且每次需要的配置可能还不同

满足依赖 @Provides

以上 @Inject 的问题都可以通过 @Provides 来解决。 @Provides 修饰一个方法,这个方法会提供一个对象,在方法里我们自己实现如何实例化一个对象,如何配置。这个方法也可以有参数,同 @Inject 修饰的构造函数,参数会被注入。

但是,@Inject 修饰的方法只能是一个 Module 的方法可以是静态的或者非静态的。而这个 Module 实际只是一个由 @Module 修饰的普通的类。

约定,@Provides 修饰的方法命名以 provide 开头,@Module 修饰的类以 Module 结尾。

@Module
class DripCoffeeModule {
@Provides static Heater provideHeater() {
return new ElectricHeater();
}

@Provides static Pump providePump(Thermosiphon pump) {
return pump;
}
}

构建对象图

@Inject 和 @Provides 修饰的类组成了一个对象图,而其中的元素因依赖而连接。而应用的入口点,就需要拿到这个图的一个根的集合(这牵扯到数据结构了,数据结构里的树有一个根,而图可以有多个根,从这个根,连接到一系列节点构成一颗树)。Dagger 通过 Component 提供这个图的根的集合。只有拿到 Component, Dagger 才能按照约定构造所有依赖的实例。

Component 是一个 @Component 修饰的接口,它定义一系列无参数方法,返回需要的类型。Dagger 会生成它的实现类,该类命名是在接口名前加 Dagger(如果你是用的Android Studio,要点编译按钮后才会生成实现类)。

@Component 注解还可以传一个参数,modules,即该 Component 所依赖的 Module

@Component(modules = DripCoffeeModule.class)
interface CoffeeShop {
  CoffeeMaker maker();
}

在应用的入口点,通过 Component 的 builder 构造 Component 的实例,需要手动创建一个 Module 的实例。

CoffeeShop coffeeShop = DaggerCoffeeShop.builder()
    .dripCoffeeModule(new DripCoffeeModule())
    .build();

总结

我们一块学习了 Dagger 中最基本的概念:

  1. @Inject 声明依赖
  2. @Provides 我们自定义如何提供一个实例
  3. @Module 修饰一个类,它内部可以定义多个 @Provides 修饰的方法
  4. @Component 修饰一个接口,它定义了依赖形成的图的一系列根。启动这个构造系统的导火索。

本文主要参考了,Dagger 官方文档

原文地址:http://blog.51cto.com/13616847/2073734

时间: 2024-08-01 22:38:01

Dagger学习 -- 基础概念的相关文章

Ext学习-基础概念,核心思想介绍

1.目标   本阶段的目标是通过学习一些基础知识来对EXTJS有个整体的了解,知道EXTJS的基础语法,核心设计思想等等 2.内容   1.基础部分学习   2.EXTJS类系统介绍   3.EXTJSMVC结构介绍   4.EXTJS数据模型介绍 3.学习流程           1.在学习之前,首先要对javaScript的基础要有个基础了解,如果不熟悉,请参考:javaScript基础之闭包   2[可选]学习了解一下EXTJS的一些常用功能:http://ziren.org/extjs/

分布式强化学习基础概念(Distributional RL )

分布式强化学习基础概念(Distributional RL) from: https://mtomassoli.github.io/2017/12/08/distributional_rl/ 1. Q-learning 在 Q-learning 中,我们想要优化如下的 loss: Distributional RL 的主要思想是:to work directly with the full distribution of the return rather than with its expec

分布式学习——基础概念篇

概述 最近这段时间一直在看分布式有关的东西,但是关于分布式自己还是不能很好的理解,所以本文对分布式基础概念进行下学习. 分布式处理 首先先了解一下分布式处理,分布式处理和集中式处理正好是相反的的体系架构,集中传输集中到式处理顾名思义就是将所有的信息都一个统一的信息中心进行处理:分布式处理就是将不同地点的,或具有不同功能的,或拥有不同数据的多台计算机利用通信网络连接起来,让各个计算机各自承担同一个工作任务的不同部分,在控制中心的管理下,同时运行,共同完成同一个工作任务. 提到分布式处理就不能不提到

【转】深度学习基础概念理解

原文链接 神经网络基础 1)神经元(Neuron)--就像形成我们大脑基本元素的神经元一样,神经元形成神经网络的基本结构.想象一下,当我们得到新信息时我们该怎么做.当我们获取信息时,我们一般会处理它,然后生成一个输出.类似地,在神经网络的情况下,神经元接收输入,处理它并产生输出,而这个输出被发送到其他神经元用于进一步处理,或者作为最终输出进行输出.  2)权重(Weights)--当输入进入神经元时,它会乘以一个权重.例如,如果一个神经元有两个输入,则每个输入将具有分配给它的一个关联权重.我们随

python学习:基础概念

Python 包管理工具解惑 python packaging 一.困惑 作为一个 Python 初学者,我在包管理上感到相当疑惑(嗯,是困惑).主要表现在下面几个方面: 这几个包管理工具有什么不同? * distutils * setuptools * distribute * disutils2 * distlib * pip 2. 什么时候该用pip,什么时候该用 setup.py ,它们有关系么? 3. easy_install . ez_setup.py . setup.py . se

一步步AS400-Cobol 上手自学入门教程01 - 基础概念(原创)

先学习基础概念 1.COBOL字符:包含: User-defined words 用户定义字符 ?System-names ?Reserved words 关键字 2.用户定义字符User-defined words:合法的定义: ? A - Z ? a - z ? 0 - 9 ? - (连字符). 3.系统名 System-names Computer-names ?Language-names ?Implementor-names: Environment-name Assignment-n

Elasticserach学习笔记-01基础概念

本文系本人根据官方文档的翻译,能力有限.水平一般,如果对想学习Elasticsearch的朋友有帮助,将是本人的莫大荣幸. 原文出处:https://www.elastic.co/guide/en/elasticsearch/reference/current/_basic_concepts.html ElasticSearch有几个核心概念,了解它们将有助于我们的整个学习过程. 近乎实时(NRT)Elasticsearch是一个近乎实时的搜索平台.这意味着从你为一个文档建立索引到该文档可被检索

【嵌入式4412开发板学习教程】Uboot教程之uboot基础概念和框架

[4412开发板教程]Uboot教程之uboot基础概念和框架 正在学习uboot,教程讲解的很详细,先上个笔记,视频上传到网盘后再补上...... 知识点: 1.操作系统分层的概念 Windows:bios→内核模式→用户模式→用户程序 linux:bootloader→内核→文件系统→用户程序 2.bootboader种类介绍 U-boot是最通用的bootboader.(210,4412等等) vivi 针对三星的ARM来定制2440上有用到 3.4412休眠问题 它可以直接跳过uboot

Linux程序设计学习笔记----多线程编程基础概念与基本操作

转载请注明出处,http://blog.csdn.net/suool/article/details/38542543,谢谢. 基本概念 线程和进程的对比 用户空间资源对比 每个进程在创建的时候都申请了新的内存空间以存储代码段\数据段\BSS段\堆\栈空间,并且这些的空间的初始化值是父进程空间的,父子进程在创建后不能互访资源. 而每个新创建的线程则仅仅申请了自己的栈,空间,与同进程的其他线程共享该进程的其他数据空间包括代码段\数据段\BSS段\堆以及打开的库,mmap映射的文件与共享的空间,使得