Dependency Injecte(依赖注入)

首先写个不使用依赖注入的示例
  • interface
// House.java
public interface House {
void prepareForWar(); void reportForWar();
}
  • 新建两个实现 House 接口的类
// Starks.java
public class Starks implements House { @Override
public void prepareForWar() {
//do something
System.out.println(this.getClass().getSimpleName()+" prepared for war");
} @Override
public void reportForWar() {
//do something
System.out.println(this.getClass().getSimpleName()+" reporting..");
}
}
// Boltons.java
public class Boltons implements House {
@Override
public void prepareForWar() {
//do something
System.out.println(this.getClass().getSimpleName()+" prepared for war");
} @Override
public void reportForWar() {
//do something
System.out.println(this.getClass().getSimpleName()+" reporting..");
}
}
  • 接着需要一个依赖于这两个的类的类
public class War {

    private Starks starks;

    private Boltons boltons;

    public War(){
starks = new Starks();
boltons = new Boltons(); starks.prepareForWar();
starks.reportForWar();
boltons.prepareForWar();
starks.reportForWar();
} }
  • 下次改用依赖注入的方式实现这个类
public class War {

    private Starks starks;
private Boltons boltons; //DI - getting dependencies from else where via constructor
public War(Starks starks, Boltons bolton){
this.starks = starks;
this.boltons = bolton;
} public void prepare(){
starks.prepareForWar();
boltons.prepareForWar();
} public void report(){
starks.reportForWar();
boltons.reportForWar();
} }
  • 从外部注入依赖的对象
public class BattleOfBastards {

    public static void main(String[] args){

        Starks starks = new Starks();
Boltons boltons = new Boltons(); War war = new War(starks,boltons);
war.prepare();
war.report();
}
}
利用dagger2进行依赖注入
  • Dagger 2 works on Annotation processor. 需要了解一定的java注解知识
  • 首先了解dagger2最常用的2个注解 @Inject@Component

@Inject Annotation

可以作用于

  • 构造器
  • 字段
  • 方法

@Inject注解告诉dagger哪些方法,构造器或者字段是需要依赖注入

But @Inject doesn’t work everywhere:

  • Interfaces can’t be constructed.
  • Third-party classes can’t be annotated.
  • Configurable objects must be configured!

@Component Annotation

作用于接口

@Componentdagger会生成一个实现该接口的class,该class会实现其中的方法,提供需要依赖的对象,相当于是一个代理

修改的代码

添加默认构造器,并添加注解@Inject

public class Boltons implements House {

    // 添加默认构造器,并添加注解@Inject
@Inject
public Boltons(){
} @Override
public void prepareForWar() {
//do something
System.out.println(this.getClass().getSimpleName()+" prepared for war");
} @Override
public void reportForWar() {
//do something
System.out.println(this.getClass().getSimpleName()+" reporting..");
}
}
public class Starks implements House {

    @Inject //Dagger 2
public Starks(){
} @Override
public void prepareForWar() {
//do something
System.out.println(this.getClass().getSimpleName()+" prepared for war");
} @Override
public void reportForWar() {
//do something
System.out.println(this.getClass().getSimpleName()+" reporting..");
}
}
public class War {

    private Starks starks;

    private Boltons boltons;

    @Inject
public War(Starks starks, Boltons bolton){
this.starks = starks;
this.boltons = bolton;
} public void prepare(){
starks.prepareForWar();
boltons.prepareForWar();
} public void report(){
starks.reportForWar();
boltons.reportForWar();
} }
  • 修改依赖加载方式
public class BattleOfBastards {

    public static void main(String[] args){
// Mannual DI
// Starks starks = new Starks();
// Boltons boltons = new Boltons();
// War war = new War(starks,boltons);
// war.prepare();
// war.report(); // Using Dagger 2
BattleComponent component = DaggerBattleComponent.create();
War war = component.getWar();
war.prepare();
war.report(); }
}
在build之后查看annotation processor 自动生成的代码
  • 如图

  • DaggerBattleComponent.java 为dagger自动生成的代码,已类名加上Dagger前缀命名, 该类实现了BattleComponent接口
package com.explore.lin.didemo.javaDIdemo;

import javax.inject.Provider;

public final class DaggerBattleComponent implements BattleComponent {
private Provider<War> warProvider; private DaggerBattleComponent(Builder builder) {
assert builder != null;
initialize(builder);
} public static Builder builder() {
return new Builder();
} public static BattleComponent create() {
return new Builder().build();
} @SuppressWarnings("unchecked")
private void initialize(final Builder builder) { this.warProvider = War_Factory.create(Starks_Factory.create(), Boltons_Factory.create());
} @Override
public War getWar() {
return new War(new Starks(), new Boltons());
} public static final class Builder {
private Builder() {} public BattleComponent build() {
return new DaggerBattleComponent(this);
}
}
}
  • 继续在component中添加方法
@Component
interface BattleComponent {
War getWar();
//adding more methods
Starks getStarks();
Boltons getBoltons();
}
  • 观察dagger2生成的DaggerBattleComponent中
  // DaggerBattleComponent.java
@Override
public War getWar() {
return new War(new Starks(), new Boltons());
} @Override
public Starks getStarks() {
return new Starks();
}
  • 如果我们删除Boltons.java构造器中的注解@Inject,会发现无法通过编译,因为在war.java的构造器中存在对Boltons的依赖
总结

比如有个classA中存在对classB的依赖,用dagger2怎么实现呢

  • 一种
class A {

    @Inject
public A() {
} @Inject
B b; void act() {
b.prepare();
}
} class B {
@Inject
public B() { } void prepare() {
System.out.println("b.prepare()");
}
} @Component
interface AComponent {
A a();
} public class InjectDemo { public static void main(String[] args) {
DaggerAComponent.create().a().act();
}
}
  • 二,什么时候使用@Provide,比如你使用第三方库,或则B中构造器没有@Inject
class AP {
@Inject
public AP() { }
@Inject
BP bp; void act() {
bp.prepare();
}
} class BP {
void prepare() {
System.out.println("bp.prepare()");
}
} @Component(modules = {APModule.class})
interface APComponent{
AP ap();
} @Module
class APModule { @Provides
BP providerBP() {
return new BP();
}
} public class ProvideDemo {
public static void main(String[] main) {
DaggerAPComponent.create().ap().act();
}
}
在android中应用dagger
  • 同样先新建不使用dagger的项目

参考https://github.com/DaiHangLin/dependencyInjecte

android dagger2使用笔记的更多相关文章

  1. Android自动化学习笔记:编写MonkeyRunner脚本的几种方式

    ---------------------------------------------------------------------------------------------------- ...

  2. Android自动化学习笔记之MonkeyRunner:官方介绍和简单实例

    ---------------------------------------------------------------------------------------------------- ...

  3. android开发学习笔记000

    使用书籍:<疯狂android讲义>——李刚著,2011年7月出版 虽然现在已2014,可我挑来跳去,还是以这本书开始我的android之旅吧. “疯狂源自梦想,技术成就辉煌.” 让我这个 ...

  4. Android动画学习笔记-Android Animation

    Android动画学习笔记-Android Animation   3.0以前,android支持两种动画模式,tween animation,frame animation,在android3.0中 ...

  5. Android 数字签名学习笔记

    Android 数字签名学习笔记 在Android系统中,所有安装到系统的应用程序都必有一个数字证书,此数字证书用于标识应用程序的作者和在应用程序之间建立信任关系,如果一个permission的pro ...

  6. Android高级编程笔记(四)深入探讨Activity(转)

    在应用程序中至少包含一个用来处理应用程序的主UI功能的主界面屏幕.这个主界面一般由多个Fragment组成,并由一组次要Activity支持.要在屏幕之间切换,就必须要启动一个新的Activity.一 ...

  7. Android群英传笔记——第十二章:Android5.X 新特性详解,Material Design UI的新体验

    Android群英传笔记--第十二章:Android5.X 新特性详解,Material Design UI的新体验 第十一章为什么不写,因为我很早之前就已经写过了,有需要的可以去看 Android高 ...

  8. Android群英传笔记——第十章:Android性能优化

    Android群英传笔记--第十章:Android性能优化 随着Android应用增多,功能越来越复杂,布局也越来越丰富了,而这些也成为了阻碍一个应用流畅运行,因此,对复杂的功能进行性能优化是创造高质 ...

  9. Android群英传笔记——第九章:Android系统信息和安全机制

    Android群英传笔记--第九章:Android系统信息和安全机制 本书也正式的进入尾声了,在android的世界了,不同的软件,硬件信息就像一个国家的经济水平,军事水平,不同的配置参数,代表着一个 ...

随机推荐

  1. 配置Spring.NET

    先引入关键的程序集 Common.Logging.dll Spring.Core.dll 在配置文件配置中: <configSections> ...... <sectionGrou ...

  2. Redis实现之对象(三)

    集合对象 集合对象的编码可以是intset或者hashtable,intset编码的集合对象使用整数集合作为底层实现,集合对象包含的所有元素都被保存在整数集合里面.举个栗子,以下代码将创建一个图1-1 ...

  3. 通过js date对象获取各种开始结束日期的示例

    有时候做一些任务计划的功能时候,需要提供一个开始时间或者结束时间,比如本周结束,本月结束,今天结束等等,因此,我参考网上的资料把相关的实现为一个项目: gitee: https://gitee.com ...

  4. Python框架之Django学习笔记(十二)

    Django站点管理 十一转眼结束,说好的充电没能顺利开展,反而悠闲的看了电视剧以及去影院看了新上映的<心花路放>.<亲爱的>以及<黄金时代>,说好的劳逸结合现在回 ...

  5. IOS开发---菜鸟学习之路--(二十四)-iOS7View被导航栏遮挡问题的解决

    (此文为复制帖,原文地址为:http://blog.sina.com.cn/s/blog_a8192bdd0101af40.html) self.navigationController.naviga ...

  6. STL 里面的几个容器简叙

    出处:http://blog.csdn.net/niushuai666/article/details/6654951 list1.list的成员函数push_back()把一个对象放到一个list的 ...

  7. python 中输入一个字符串,判断这个字符串中有多少个字符、数字、空格、特殊字符

    # -*- coding: utf8 -*- # Author:wxq #python 2.7 #首先定义一个字符串 str1 = raw_input('请输入一个字符:') #初始化字符.数字.空格 ...

  8. iBATIS 框架主要的类层次结构

    iBATIS 框架主要的类层次结构 总体来说 iBATIS 的系统结构还是比较简单的,它主要完成两件事情: 根据 JDBC 规范建立与数据库的连接: 通过反射打通 Java 对象与数据库参数交互之间相 ...

  9. 【bzoj4589】Hard Nim FWT

    题目描述 Claris和NanoApe在玩石子游戏,他们有n堆石子,规则如下: 1. Claris和NanoApe两个人轮流拿石子,Claris先拿. 2. 每次只能从一堆中取若干个,可将一堆全取走, ...

  10. hihoCoder #1661 数组区间

    题目大意 给出 $1$ 到 $n$ 的一个排列($n\le 10^5$),记做 $a_1, a_2, \dots, a_n$ .(注:原题面表述为:"给定 $n$ 个互不相同且不超过 $n$ ...