dagger2 (一)

研究了下dagger2,现在结合dagger2生成的代码分析下。
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0213/2478.html 比较全面

apply plugin: 'com.neenbedankt.android-apt'
buildscript {
  repositories {
  jcenter()
}
dependencies {
  classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
  }
}
android {
...
}
dependencies {
apt 'com.google.dagger:dagger-compiler:2.0.2'
compile 'com.google.dagger:dagger:2.0.2'
provided 'javax.annotation:jsr250-api:1.0'
}

Component

被Component标注的接口。这里是连接注入实例与被注入实例的桥梁。

@Component
public interface ApplicationComponent {
}

成功编译时自动生成一个实现类Dagger***实现我们定义的接口。

@Generated("dagger.internal.codegen.ComponentProcessor")
public final class DaggerApplicationComponent implements ApplicationComponent {
  private DaggerApplicationComponent(Builder builder) {  
    assert builder != null;
  }

  public static Builder builder() {  
    return new Builder();
  }

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

  public static final class Builder {
    private Builder() {  
    }
  
    public ApplicationComponent build() {  
      return new DaggerApplicationComponent(this);
    }
  }
}

这个实现类内部有一个静态不可被继承的内部类Builder。可以通过Dagger.create()获取到该实现类的实例,也可以通过Dagger.builder.build()获取。
显然这样的实现类并没有什么卵用,要将我们需要注入的对象与被注入对象联系起来则需要在conponent接口中写一个返回值为void的方法。

@Component
public interface ApplicationComponent {

    void inject(MyApp app);

}

生成的代码

@Generated("dagger.internal.codegen.ComponentProcessor")
public final class DaggerApplicationComponent implements ApplicationComponent {
  private DaggerApplicationComponent(Builder builder) {
    assert builder != null;
    initialize(builder);
  }

  public static Builder builder() {
    return new Builder();
  }

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

  private void initialize(final Builder builder) {
  }

  @Override
  public void inject(MyApp app) {
    MembersInjectors.noOp().injectMembers(app);
  }

  public static final class Builder {
    private Builder() {
    }

    public ApplicationComponent build() {
      return new DaggerApplicationComponent(this);
    }
  }
}

可以看到生成的代码中有个方法。内部实现都是MembersInjectors.noOp().injectMembers(app),这个MembersInjectors又是什么。

public final class MembersInjectors {
  @SuppressWarnings("unchecked")
  public static  MembersInjector noOp() {
  return (MembersInjector) NoOpMembersInjector.INSTANCE;
  }

  private static enum NoOpMembersInjector implements MembersInjector {
    INSTANCE;

    @Override public void injectMembers(Object instance) {
      if (instance == null) {
        throw new NullPointerException();
      }
    }
  }
  @SuppressWarnings("unchecked")
  public static  MembersInjector delegatingTo(MembersInjector delegate) {
    return (MembersInjector) delegate;
  }

  private MembersInjectors() {}
}
 
 

injectMembers()这个方法只是对参数进行了非空判断,这个方法似乎也是什么卵用没有。
在看我们定义的接口里的方法inject(MyApp app),参数app只是被注入的对象,注入的对象在哪里传入?这就需要写在被注入的对象里了。

public class MyApp extends Application {

    @Inject
    User user;

    @Override
    public void onCreate() {
        super.onCreate();
        DaggerApplicationComponent.create().inject(this);
    }
}

在被注入的对象里创建成员变量,用Inject标注。再编译之后。

@Generated("dagger.internal.codegen.ComponentProcessor")
public final class DaggerApplicationComponent implements ApplicationComponent {
  private MembersInjector myAppMembersInjector;

  private DaggerApplicationComponent(Builder builder) {  
    assert builder != null;
    initialize(builder);
  }

  public static Builder builder() {  
    return new Builder();
  }

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

  private void initialize(final Builder builder) {  
    this.myAppMembersInjector = MyApp_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), User_Factory.create());
  }

  @Override
  public void inject(MyApp app) {  
    myAppMembersInjector.injectMembers(app);
  }

  public static final class Builder {
    private Builder() {  
    }
  
    public ApplicationComponent build() {  
      return new DaggerApplicationComponent(this);
    }
  }
}

Dagger的inject方法里是myAppMembersInjector.injectMembers(app),好像嗯刚才的MembersInjector.injectMembers()不一样。追进代码到MyApp_MembersInjector 。这个也是编译时创建的类。

@Generated("dagger.internal.codegen.ComponentProcessor")
public final class MyApp_MembersInjector implements MembersInjector {
  private final MembersInjector supertypeInjector;
  private final Provider userProvider;

  public MyApp_MembersInjector(MembersInjector supertypeInjector, Provider userProvider) {
    assert supertypeInjector != null;
    this.supertypeInjector = supertypeInjector;
    assert userProvider != null;
    this.userProvider = userProvider;
  }

  @Override
  public void injectMembers(MyApp instance) {
    if (instance == null) {
      throw new NullPointerException("Cannot inject members into a null reference");
    }
    supertypeInjector.injectMembers(instance);
    instance.user = userProvider.get();
  }

  public static MembersInjector create(MembersInjector supertypeInjector, Provider userProvider) {
      return new MyApp_MembersInjector(supertypeInjector, userProvider);
  }
}

看它的injectMembers()方法,先调用了supertypeInjector.injectMembers(instance),再将userProvider.get()的返回值赋值给被注入对象app的user变量。
追进userProviders.get()方法。

@Generated("dagger.internal.codegen.ComponentProcessor")
public enum User_Factory implements Factory {
INSTANCE;

  @Override
  public User get() {  
    return new User();
  }

  public static Factory create() {  
    return INSTANCE;
  }
}

方法内部实际是创建了一个对象返回。至此,就可以明白被注入的实例是怎样注入到参数中的。supertypeInjector.injectMembers(instance)是递归将父类需要注入的实例注入参数中。User对象的构造方法需要且只能有一个被Inject标注,否则会报错。

public class User {

    @Inject
    public User(){

    }

}

在需要的地方通过DaggerApplicationComponent.create().inject(this)就可以将需要注入的实例注入到被注入对象中。

你可能感兴趣的:(dagger2 (一))