将Dagger系列的咖啡壶样例再做一下简化,作为Dagger2的入门的第一个小样例。

场景描写叙述:有一个电水壶,它使用一个加热器来烧水。电水壶具备的功能有:開始加热(on方法),结束加热(off方法),倒水(brew方法)。

正确使用Dagger2要依照下面5个步骤来进行:

1.确定依赖对象和被依赖对象

本例中。水壶是依赖对象(dependent object),加热器是被依赖对象(dependent object’s dependency)。而与此同一时候,加热器本身并不依赖谁,所以它是一个独立的个体(independent
model)。

加热器:src/bean/Heater.java

public class Heater {
private boolean isHot;
public void on(){
System.out.println("開始烧开水啦");
isHot = true;
}
public void off(){
System.out.println("关闭加热器");
isHot = false;
}
public boolean isHot(){
return isHot;
}
}

电水壶:src/bean/Kettle.java

public class Kettle {
private Heater heater;//电水壶依赖于加热器 public Kettle(Heater heater) {
super();
this.heater = heater;
}
public void on(){
heater.on();
}
public void off(){
heater.off();
}
public void brew(){
if(heater.isHot()){
System.out.println("倒一杯开水");
}
}
}

2.创建@Module类

Module类的作用就是提供各种方法,来返回满足依赖关系的对象。这些方法须要加入上@Provides注解。

src/module/KettleModule.java

@Module
public class KettleModule {
@Singleton
@Provides
Heater providesHeater(){
return new Heater();
}
@Singleton
@Provides
Kettle providesKettle(Heater heater){
return new Kettle(heater);
}
}

3.当有了@Module类,提供所需的依赖和被依赖对象,那么我们就在须要的地方进行取用就可以。

取用的方式是通过@Inject注解。如今改动下面之前的Kettle类:

<pre name="code" class="java" style="font-size: 18px;">public class Kettle {
private Heater heater;//电水壶依赖于加热器
<span style="color:#ff6666;">@Inject</span>
public Kettle(Heater heater) {
super();
this.heater = heater;
}
public void on(){
heater.on();
}
public void off(){
heater.off();
}
public void brew(){
if(heater.isHot()){
System.out.println("倒一杯开水");
}
}
}

唯一改动的就是为构造器加入了@Inject注解。

Dagger2中。@Inject注解能够加入在构造器、方法和属性本身的前面。本例就通过构造器进行注入。

4.创建一个接口,让@Inject和@Module建立起联系

写一个接口,并用@Component进行注解。该注解有一个属性module。它用来指明与@Inject建立联系的将是哪一个(或哪一些)@Module类。假设@Inject和@Module匹配正确,那么在接口中定义的方法的返回值对象,都将是被正确注入了依赖关系的对象了:

src/module/KettleComponent:

@Singleton
@Component(modules=KettleModule.class)
public interface KettleComponent {
Kettle providesKettle();
}

5.获得第4步中声明的接口对象的实例,进而获得接口中定义方法的返回值

@Component接口的实现类由Dagger2自己主动生成。这个类的命名规范是Dagger前缀加上@Component类的名称,那么本例中,这个类的名称就是DaggerKettleComponent了。

写一个測试类,測试一下注入的结果:

src/main/Test:

public class Test {
public static void main(String[] args) {
KettleComponent component = DaggerKettleComponent.builder().build();
Kettle kettle = component.providesKettle();
kettle.on();
kettle.brew();
kettle.off();
}
}

这里一定要注意,DaggerKettleComponent类是Daager2依据注解自己主动生成的一个类。我们能够看一下这个类的源代码。就知道为什么要这么调用才干生成一个KettleComponent对象了。

@Generated("dagger.internal.codegen.ComponentProcessor")
public final class DaggerKettleComponent implements KettleComponent {
private Provider<Heater> providesHeaterProvider;
private Provider<Kettle> providesKettleProvider; private DaggerKettleComponent(Builder builder) {
assert builder != null;
initialize(builder);
} public static Builder builder() {
return new Builder();
} public static KettleComponent create() {
return builder().build();
} private void initialize(final Builder builder) {
this.providesHeaterProvider = ScopedProvider.create(KettleModule_ProvidesHeaterFactory.create(builder.kettleModule));
this.providesKettleProvider = ScopedProvider.create(KettleModule_ProvidesKettleFactory.create(builder.kettleModule, providesHeaterProvider));
} @Override
public Kettle providesKettle() {
return providesKettleProvider.get();
} public static final class Builder {
private KettleModule kettleModule; private Builder() {
} public KettleComponent build() {
if (kettleModule == null) {
this.kettleModule = new KettleModule();
}
return new DaggerKettleComponent(this);
} public Builder kettleModule(KettleModule kettleModule) {
if (kettleModule == null) {
throw new NullPointerException("kettleModule");
}
this.kettleModule = kettleModule;
return this;
}
}
}

DaggerKettleComponent实现了KettleCommpoment接口,并重写了providesKettle方法。

首先调用静态方法builder是为了创建静态内部类Builder类的对象,创建对象后调用方法kettleModule方法为Builder的kettleModule属性赋值,随后再调用静态内部类Builder对象的build方法创建DaggerKettleComponent的对象。

在DaggerKettleComponent构造器中会首先对静态内部类Builder对象进行一下判空,然后调用initialize(builder)方法,利用这个静态内部类Builder对象为自己的两个属性赋值:providesHeaterProvider属性和providesKettleProvider属性。而且providesKettleProvider属性值的创建要依赖于providesHeaterProvider属性值。随着providesHeaterProvider属性和providesKettleProvider属性初始化完成,DaggerKettleComponent对象也就创建完成了。

当调用providesKettle方法的时候。返回的是providesKettleProvider的get方法的返回值。

最后測试程序的运行结果为:

使用Dagger2创建的第一个小样例的更多相关文章

  1. Robotframework(2):创建RF第一条可执行的用例

    转载:http://www.cnblogs.com/CCGGAAG/p/7800323.html 上篇,我们说了如何配置基础的环境,配置好了python2.wxPython .robot framew ...

  2. SpringMVC+Spring+Hibernate的小样例

    Strusts2+Spring+Hibernate尽管是主流的WEB开发框架,可是SpringMVC有越来越多的人使用了.确实也很好用.用得爽! 这里实现了一个SpringMVC+Spring+Hib ...

  3. Android开发之 Windows环境下通过Eclipse创建的第一个安卓应用程序(图文详细步骤)

    第一篇  windows环境下搭建创建的第一个安卓应用程序 为了方便,我这里只采用了一体包进行演示. 一.下载安卓环境的一体包. 官网下载:安卓官网(一般被墙了) 网盘下载: http://yunpa ...

  4. Spring DI模式 小样例

           今儿跟同事讨论起来spring早期的,通过大篇幅xml的配置演变到今天annotation的过程,然后随手写了个小样例,感觉还不错,贴到这里留个纪念. 样例就是用JAVA API的方式, ...

  5. 简单的ADO.NET连接数据小样例

    ADO.NET连接数据库的样例如下: using System; using System.Collections.Generic; using System.ComponentModel; usin ...

  6. Robot Framework自动化测试(二)第一个用例

    RIDE启动界面: 首先创建一个Test project File-New Project ,选择Directory类型 在创建的文件夹上右键,创建一个Test Suite Openbaidu, NE ...

  7. Java 小样例:图书馆课程设计(Java 8 版)

    用 Java 模拟一个图书馆.包含创建图书.创建读者.借书.还书.列出全部图书.列出全部读者.列出已借出的图书.列出过期未还的图书等功能. 每一个读者最多仅仅能借 3 本书,每一个书最多仅仅能借 3 ...

  8. php单例模式实现对象只被创建一次 mysql单例操作类

    这是我在php面试题中遇到的一道试题,单例模式按字面来看就是某一个类只有一个实例,这样做的好处还是很大的,比如说数据库的连接,我们只需要实例化一次,不需要每次都去new了,这样极大的降低了资源的耗费. ...

  9. 决策树python实现小样例

    我们经常使用决策树处理分类问题,近年来的调查表明决策树也是经常使用的数据挖掘算法K-NN可以完成多分类任务,但是它最大的缺点是无法给出数据的内在含义,决策树的主要优势在于数据形式非常容易理解决策树的优 ...

随机推荐

  1. android mvp高速开发框架介绍(dileber使用之图片下载工具)

    这几天忙着工作- 今天抽时间又把框架的bug处理了一下--并且把volley的源代码改动了一下 android mvp框架:dileber(https://github.com/dileber/dil ...

  2. unknown argument: &#39;-websockets&#39;

    找到building setting找到other link flgs里把里面'-websockets删掉

  3. 2014.04.16,读书,读书笔记-《Matlab R2014a完全自学一本通》-第17章 图形用户界面

    界面对象分三类: 用户控件对象(uicontrol) 下拉式菜单对象(uimenu) 内容式菜单对象(uicontextmenu) 创建用户界面: 1.命令行方式 采用uicontrol来创建控件对象 ...

  4. Python 下的 return 关键字

    def make_sum(a, b): return ('+', a, b) >> make_sum(1, 2) ('+', 1, 2) 显示地返回一个元组(tuple),当然 retur ...

  5. 【POJ 2828】Buy Tickets

    [题目链接] http://poj.org/problem?id=2828 [算法] 离线用线段树维护序列即可 [代码] #include <algorithm> #include < ...

  6. leetcode 系列文章目录

    leetcode 系列文章目录 0. 两数之和1. 两数相加 2. 无重复字符的最长子串 3. 寻找两个有序数组的中位数 4. 最长回文子串 5. Z 字形变换 6. 整数反转 7. 字符串转换整数 ...

  7. Combo Select – jQuery可搜索下拉框插件

    今天用到另一款jq插件..插件就是无脑,,引入相关文件,开始撸吧 引入相关文件: <link href="~/Scripts/combo-select/combo.select.css ...

  8. 常用相关linux命令

    查看进程netstat -tnlp | egrep "(9097)" lsof -i:9097 ps -ef | grep kafka 观察句柄变化lsof -p $pid | w ...

  9. node——进阶版服务器根据不同请求作出不同响应+响应html文件等文件

    文件目录结构如下 resource文件里面放了css文件和图片等,view文件里面是html文件 <!DOCTYPE html> <html lang="en"& ...

  10. Python IDE和编辑器

    1.什么是IDE? IDE也就是集成开发环境,较常用的有PyCharm 2.编辑器 (1)Sublime Text Sublime Text 具有漂亮的用户界面和强大的功能,例如代码缩略图,Pytho ...