目录
  1. 1. 何为 Dagger?
    1. 1.1. 依赖注入
    2. 1.2. 编译时注解解析
    3. 1.3. Dagger2实现原理
      1. 1.3.1. Inject注解
重拾Android-【必知必会SDK】之从Dagger2到Hilt再到Koin

依赖注入在后端领域开发是一项非常流行的设计模式,在 Google 接手了 Dagger 项目的开发工作之后,随之而来也给移动端带来了新的生机。

何为 Dagger?

[Dagger](http://square.github.io/dagger/) —— A fast dependency injector for Java and Android.

它是一个适用于Java 和 Android 开发的编译注解 依赖注入(Dependency Injection, DI) 框架,最早是由Square公司 —— 美国一家移动支付公司开源的(我们的Android之神就入职这家),后来经由Google维护,继而开发出 Dagger2 ,其是在 Dagger1 基础之上开发的一个“船新”版本,但是仍然与Dagger1有比较多的相似之处。只是在相关 API 上,Dagger2 尝试做了更多的修改。当然要认识这一设计模式,首先我们先来了解什么是 依赖注入

依赖注入

什么是依赖注入?

就是目标类中所依赖的其他的类的初始化过程,不是通过手动编码的方式创建。

大概十五年前,英国著名软件工程师 Marting Fowler 就针对轻量级容器【当时的技术圈顶级流量话题】发表了一篇文章《Inversion of Control Containers and the Dependency Injection pattern》,如果想看中文版翻译,请看这里。这种控制反转的设计模式,后来被唤作 —— 依赖注入。它是由一个装配器来创建对象,并将对象的实例传递给需要依赖的对象,其目的就在于降低对象之期间的耦合性。

在java中,有这几种常见的场景,可以关联对象1和对象2的依赖关系:

  • 对象1作为对象2的构造函数或者方法中的参数;

  • 对象1是对象2的成员变量,或者对象1是对象2方法中的局部变量;

  • 对象1的静态方法被对象2调用。

我们知道,代码耦合性是衡量类与类或模块与模块之间依赖程度的表现之一,SOLID原则:单一职责、开放关闭、里式替换、接口隔离、依赖倒置,这几大原则无一例外均在提现解耦的思想。因此,利用依赖注入的方式,开发者可以不用考虑对象创建,而是依赖装配器将对象的依赖注入进去。

基于此,我们可以将Dagger理解为这样一个框架:利用编译时注解解析,创建对象与对象之间的依赖关系的容器,以及被依赖对象的实例,并将依赖关系注入所需的对象中。

编译时注解解析

传统的依赖注入框架利用Java反射机制实现依赖注入,这样不好的后果就是加载耗时,也耗损性能。Dagger2 是基于编译时注解来解析,通过在编译期间进行依赖注入,在性能上绝对能胜之。APT —— 注解处理器,它是javac的一个工具,用于编译时处理注解,从而生成Java文件。而Dagger2正式利用这一技术实现了在编译期间解析注解,生成相应的装配器等,完成依赖注入。

Dagger2实现原理

Inject注解

Inject 注解是javax包提供的一个用于依赖注入的注解,是Java依赖注入规范(JSR330)提供的标准注解之一。源码如下:

@Target({ METHOD, CONSTRUCTOR, FIELD })
@Retention(RUNTIME)
@Documented
public @interface Inject {}

有关注解的相关知识可以参考这篇文章,由上可以看出,Inject注解可用于标注方法构造方法字段,当Inject注解标注构造方法时,表示Dagger2创建对象实例时,将调用Inject注解标注的构造方法。可以这样理解:

如果一个类没有标注Inject注解,它将无法通过Dagger2实例化,而当 Inject 注解标注构造方法时,也将指示Dagger2构造方法中声明的参数需要被注入依赖关系。

这里要注意,当一个类有多个构造方法,那么就不能通过Inject同时标注多个构造方法,否则会报错,这时如若需要,可以通过 限定符Qualifier 注解协助完成。

打赏
  • 微信
  • 支付宝

评论