Dagger2进阶-编译生成源码解读

前言

    

       

        Dagger2的介绍和配置

        Dagger2基础的使用

        Dagger2进阶-编译生成源码解读

        Dagger2进阶-范围的控制(Scope和Singleton)

        Dagger2进阶-Scope的源码探究

        项目源代码传送门


    根据前面两篇文章的解读,大家一定对Dagger2的用法有自己的理解和应用,但是日常开发过程中会根据业务的复杂度,我们会出现各种各样的问题,这就要求大家对Dagger2的原理和编译生成的源码进行解读找出问题的答案。下面我们会分几个阶段进行源码解读,从简单到困难。

@Inject作用在构造方法上

    当项目中只有一个@Inject的时候,我们会看到什么呢,以Goods为列子:

    

根据上图,我们很清晰的知道,如果只用@Inject会生成一个工厂类,这个工厂类也非常简单就是通过get()方法生成一个对象。

@Inject作用字段属性上

    当我们使用@Inject获取一个对象的时候,我们看看发生了什么,编译:


我们可以看到,生成了一个XXX_MembersInjector:


其中,我们看构造方法就是传入工厂类赋值,create就是创建一个MemberInjector对象,其实最核心的是以下代码:

 @Override
  public void injectMembers(MainActivity instance) {
    if (instance == null) {
      throw new NullPointerException("Cannot inject members into a null reference");
    }
    instance.mGoods = mGoodsProvider.get();
  }

我们可以看到instance其实就是我们需要Goods对象的Activity,instance.mGoods = mGoodsProvider.get();语句就是为activity对象中的mGoods创建一个新的Goods对象,而对象Goods通过工厂类提供,So,XXX_MembersInjector就是赋值的作用,这里就说明为什么我们@Inject修饰的字段为什么不能使用private的权限了。

我们做一个尝试,我们在同一个Activity注入三个Goods对象会怎样变化呢?


如果自己尝试可以看出来,其他逻辑什么都没变化,变化的是他也是赋值了三次,生成了三次新的对象。

看完以上源码我们解决如下疑问:

1.为什么默认是多例的?

    因为工厂类get(),返回是new XX(),直接赋值肯定是不是单例;

2.为什么需要@Component才能获取对象的引用?

  因为我们不知道MainActivity 这个对象是什么 得有人告诉我,@Component就提供了这个职能。

使用了@Component

    当我们第一次使用@Component什么都不添加会产生什么代码呢?

    

    看上面可以比较出,生成了一个以Dagger+XXX的类,这个类就是对外的注入类。

    看代码也是很好解读的:

首先代码模板有一个建造类,使用建造类生成一个Dagger+XXX对象

然后调用构造方法里面的initialize(final Builder builder)初始化mainActivityMembersInjector对象,mainActivityMembersInjector对象就是之前的XXX_MembersInjector

最后我们看看,我们Activity最不可少的inject(object)方法,这个方法就是调用XXX_MembersInjector里面的injectMembers这里就把我们的activity和Goods对象赋值上了,所以@Component的职责,就是一个中介,我更倾向于把他当成一个管理类。



使用了@Module和@Provides

我们看到,类没有增加,还是三个,只是工厂类的命名修改了,我们来查看一下里面的代码,先看工厂类。。


跟用@Inject的区别在于,这里多了个Module对象,跟@Injetc一样 也是通过get()获取到一个对象,只是这里再用一个Module做了衔接。

XX_MembersInjector对象没有改变任何代码也是用来赋值引用。


Dagger+XX这个类主要改变在创建类中,多了一个ObjectModule对象,这个对象,就是我们的模块对象,是提供新建对象,根据传入的Module对象传入工厂类中,生成相应的对象。


猜你喜欢

转载自blog.csdn.net/u010782846/article/details/79832717
今日推荐