Dagger2代码分析

0

传说中的android三件套,Rxjava,Dagger,MVP火的不能再火了,今天我们通过代码看看Dagger2是怎么实现的。
Dagger2中比较重要的注解:
@Module用来标注Module类,Module直接粗暴地说就是一个存放我们需要实例的容器,我们需要的实例都通过Module来获取
@Component连接桥梁,注入器,Dagger2最重要的一个作用就是解耦,所以我们需要一个桥梁来把提供实例和需要实例的对象联系起来。
@Inject标注我们那些实例需要注入,或者那个构造为我们提供实例

看代码MainActivity:

public class MainActivity extends AppCompatActivity {
    @Inject
    UserInfo userInfo;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       //桥梁
        MainComponent mainComponent = DaggerMainComponent.builder().mainModle(new MainModle()).build();
        //注入操作
        mainComponent.inject(this);

        Log.e("Main", userInfo.hashCode() + "");
    }
}

MainActivity很简单, @Inject标注需要注入的对象。
MainComponent代码:

@Component(modules =MainModle.class )//桥梁,建立联系
public interface MainComponent {
    void inject(MainActivity mainActivity);
}

MainModle代码:

@Module
public class MainModle {
    @Provides//提供实例
    UserInfo provideUserInfo(){
        return new UserInfo();
    }
}

代码很简单,Dagger最简单最标准的用法。我们主要来分析一下他是怎么实现注入的。
MainComponent是一个接口,我们首先看看他的实现类DaggerMainComponent(rebuild自动生成
),我们可以看出来DaggerMainComponent是根据Builder模式创建出来的,看下代码:

@Generated("dagger.internal.codegen.ComponentProcessor")
    //Provider是一个接口,只有一个get方法,get方法返回的类型就是我们传进去的泛型
  private Provider<UserInfo> provideUserInfoProvider;
  //MembersInjector也是一个接口,一个方法injectMembers
  private MembersInjector<MainActivity> mainActivityMembersInjector;

  private DaggerMainComponent(Builder builder) {  
  //处理builder对象
    initialize(builder);
  }
    //builder方法,返回一个Builder对象
  public static Builder builder() {  
    return new Builder();
  }

  public static MainComponent create() {  
    return builder().build();
  }

  private void initialize(final Builder builder) {  
    this.provideUserInfoProvider = MainModle_ProvideUserInfoFactory.create(builder.mainModle);
    //MembersInjectors.noOp()好像没什么大的用处,这里就不做解释了
    //如果有大神知道请指教,不胜感激
    this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUserInfoProvider);
  }

  @Override
  public void inject(MainActivity mainActivity) {  
    mainActivityMembersInjector.injectMembers(mainActivity);
  }
    
    
  public static final class Builder {
    private MainModle mainModle;
  
    private Builder() {  
    }
     //调用build方法,创建桥梁
    public MainComponent build() {  
      if (mainModle == null) {
        this.mainModle = new MainModle();
      }
      return new DaggerMainComponent(this);
    }
    
    public Builder mainModle(MainModle mainModle) {  
      if (mainModle == null) {
        throw new NullPointerException("mainModle");
      }
      //给mainModle 赋值
      this.mainModle = mainModle;
      return this;
    }
  }
}

上面写注释了,然后我们着重看initialize和inject两个方法,首先我们看看initialize方法,我们看看是怎么给provideUserInfoProvider 赋值的,通过该对象的get方法我们就可以得到UserInfo实例了。

/**
*Factory是一个Provider的子类接口
*/
@Generated("dagger.internal.codegen.ComponentProcessor")
public final class MainModle_ProvideUserInfoFactory implements Factory<UserInfo> {
  private final MainModle module;

  public MainModle_ProvideUserInfoFactory(MainModle module) {  
    assert module != null;
    this.module = module;
  }
//实现get方法,我们可以看到在这里调用了我们MainModle 的provideUserInfo方法
//在这里我们也可以看到如果我们在provideUserInfo方法中返回null会直接抛出异常。
  @Override
  public UserInfo get() {  
  
    UserInfo provided = module.provideUserInfo();
    if (provided == null) {
      throw new NullPointerException("Cannot return null from a non-@Nullable @Provides method");
    }
    return provided;
  }
//外面调用的create方法
  public static Factory<UserInfo> create(MainModle module) {  
    return new MainModle_ProvideUserInfoFactory(module);
  }
}

我们可以看出来,这个get方法中返回的对象,就是我们在MainModle中返回的对象。很简单的一个类,就一个方法,没什么可说的。我们继续看是怎么给mainActivityMembersInjector赋值的。

@Generated("dagger.internal.codegen.ComponentProcessor")
public final class MainActivity_MembersInjector implements MembersInjector<MainActivity> {
  private final MembersInjector<AppCompatActivity> supertypeInjector;
  private final Provider<UserInfo> userInfoProvider;

  public MainActivity_MembersInjector(MembersInjector<AppCompatActivity> supertypeInjector, Provider<UserInfo> userInfoProvider) { 
  //赋值 
    assert supertypeInjector != null;
    this.supertypeInjector = supertypeInjector;
    assert userInfoProvider != null;
    this.userInfoProvider = userInfoProvider;
  }
//这个方法使我们重点关注的
  @Override
  public void injectMembers(MainActivity instance) { 
  //非空判断 
    if (instance == null) {
      throw new NullPointerException("Cannot inject members into a null reference");
    }
    
    supertypeInjector.injectMembers(instance);
    //真正的赋值操作,所有的一切都为了这一步
    //MainActivity中我们用@inject标注的成员变量userInfo 
    //用userInfoProvider的get方法获取UserInfo对象赋值给他
    //实际上就是MainModle中provideUserInfo方法的返回值
    instance.userInfo = userInfoProvider.get();
  }

  public static MembersInjector<MainActivity> create(MembersInjector<AppCompatActivity> supertypeInjector, Provider<UserInfo> userInfoProvider) {  
      return new MainActivity_MembersInjector(supertypeInjector, userInfoProvider);
  }
}

接着我们看inject方法,在inject方法中,我们调用了mainActivityMembersInjector的injectMembers方法,也就是我们刚刚看的真是赋值的操作。到这里就完成了所有的赋值操作。
Dagger原理很简单,在Module中有多少个@Provider标注的方法,就会生成多少个Provider类,在这些类中重写get方法,根据返回值类型调用Module不同的方法。然后把这些Provider对象传递传递给注入器对象,再注入器对象中,我们找到页面上所有需要注入赋值的对象,也就是用@inject标注的对象,用不同的Provider的get方法给这些需要注入的对象赋值。

新司机上路请大家多多指教。
大家可以关注一下,一起学习一起进步。
这里写图片描述


如果觉得我的文章对你有用,请随意赞赏

你可能感兴趣的

载入中...