Dagger中的注解

@Module

@Module注解在类或接口上,表明该类或接口用于提供相关依赖。该类或接口中使用的注解有@Provides,@Binds,@IntoSet,@IntoMap。

@Provides

最常用,注解在非抽象方法上,返回值是程序中需要用到的依赖。
代码:


@Module
public class ProvidesModule {
  /*  形式一:自己构建Windable实例
     @Provides
    public Windable provideWindable(){
        return new WindableImpl();
    }*/

    /**
     * 形式二:让Dagger构建Windable实例,此时需要在WindableImpl构造函数上打上@Inject注解
     */
    @Provides
    public Windable provideWindable(WindableImpl windable){
        return windable;
    }
}

针对@Provides注解,编译期Dagger会生成格式为:
Module类名_方法名Factory 的类并且实现了Factory接口。
针对本例生成的类就是ProvidesModule_ProvideWindableFactory

public final class ProvidesModule_ProvideWindableFactory implements Factory {
  private final ProvidesModule module;

  private final Provider windableProvider;

  public ProvidesModule_ProvideWindableFactory(
      ProvidesModule module, Provider windableProvider) {
    this.module = module;
    this.windableProvider = windableProvider;
  }

  @Override
  public Windable get() {
    return provideInstance(module, windableProvider);
  }

  public static Windable provideInstance(
      ProvidesModule module, Provider windableProvider) {
    return proxyProvideWindable(module, windableProvider.get());
  }

  public static ProvidesModule_ProvideWindableFactory create(
      ProvidesModule module, Provider windableProvider) {
    return new ProvidesModule_ProvideWindableFactory(module, windableProvider);
  }

  public static Windable proxyProvideWindable(ProvidesModule instance, WindableImpl windable) {
    return Preconditions.checkNotNull(
        instance.provideWindable(windable),
        "Cannot return null from a non-@Nullable @Provides method");
  }
}

生成的类的格式也是相对固定的。
一个静态create方法,返回值是该Factory类实例。
一个构造函数。
一个get方法,来自Factory接口,用于返回依赖。

注意:每个用@Provides注解的方法都会生成相应的Factory类。

@Binds

也是用于提供依赖,跟@Provides注解功能一样。不同的是@Binds注解于抽象方法上,返回值是依赖的接口或父类型或本类型,方法只有一个参数,就是返回值的实现者。既然@Binds注解于抽象方法,那么@Module注解的类就必须是接口或抽象类了。
代码:

@Module
public interface BindsModule {
    /**
     * 注解于抽象方法,只能有一个参数
     * @param windable
     * @return
     */
    @Binds
    Windable provideWindable(WindableImpl windable);
}

@IntoSet

@IntoSet需要联合@Provides一起使用,@IntoSet注解的方法表示方法返回值放入一个Set集合中,多个@IntoSet注解的方法,若方法返回值类型一致,则会放入同一个Set集合中。

@Module
public class IntoSetModule {

    @Provides
    @IntoSet
    public String provideA(){
        return "A";
    }

    @Provides
    @IntoSet
    public String provideB(){
        return "B";
    }
}

public class IntoSetDemo {

    @Inject
    Set letters;
    IntoSetDemo(){
    }
    public static void main(String[] args){
        IntoSetDemo demo=new IntoSetDemo();
        DaggerIntoSetComponent.create().inject(demo);

        for (String letter:demo.letters){
            System.out.print(letter);
        }
    }
}

Module类中的provideA和provideB方法的返回值被放入同一个Set集合中,所以该例的输出结果是AB。

@IntoMap

@IntoMap需要联合@IntKey,@StringKey或者自定义的@MapKey以及@Provides一起使用。如果map的key为int类型,则用@IntKey,为String类型,则用@StringKey,如果为其他类型,则需要自定义注解,并在自定义注解上打上@MapKey。

@Module
public class IntoMapModule {

    @Provides
    @IntoMap
    @IntKey(1)
    public String provideNameA(){
        return "nameA";
    }

    @Provides
    @IntoMap
    @IntKey(2)
    public String provideNameB(){
        return "nameB";
    }
}

public class IntoMapDemo {

    @Inject
    Map map;
    IntoMapDemo(){
    }
    public static void main(String[] args){
        IntoMapDemo demo=new IntoMapDemo();
        DaggerIntoMapComponent.create().inject(demo);

      System.out.println("key=1,value="+demo.map.get(1));
      System.out.println("key=2,value="+demo.map.get(2));
    }
}

IntoMapModule类中的provideNameA方法指定了key为1,value为nameA,provideNameB方法指定了key为2,value为nameB,他们被放入同一个map中。所以程序的输出结果是

key=1,value=nameA
key=2,value=nameB

@Component

@Component 注解的类(一般是接口或抽象类)用于为具体的类注入依赖。
@Component 注解有两个属性:
一个是modules属性,关联相关的Module
一个是dependencies属性,关联子Component

一般需要提供一个inject()方法,参数是需要注入的类;当然也可以定义一个直接获取依赖的方法,比如Activity类中需要注入一个Presenter对象,可以直接在Component接口中定义一个presenter方法,在Activity类中需要使用Presenter时使用component.presenter()就可以了。
a.inject法:

@Component(modules = MyModule.class)
public interface MyComponent {

    /**
     * 定义一个inject方法,注入ComponentDemo需要的依赖
     * @param componentDemo
     */
    void inject(ComponentDemo componentDemo);
}

public class ComponentDemo {

    @Inject
    MyService myService;

    ComponentDemo(){
    }

    public static void main(String args[]){
        ComponentDemo componentDemo=new ComponentDemo();
        //将MyService注入
        DaggerMyComponent.create().inject(componentDemo);
        componentDemo.myService.serve();
    }
}

MyModule提供了MyService实例。

b.Component提供一个myService()方法

@Component(modules = MyModule.class)
public interface MyComponent {
    //定义一个方法提供依赖
    MyService myService();
}
public class ComponentDemo {
    MyService myService;
    ComponentDemo(){
    }

    public static void main(String args[]){
        ComponentDemo componentDemo=new ComponentDemo(); 
        componentDemo.myService=DaggerMyComponent
                  .create()    
                  .myService();
        componentDemo.myService.serve();
    }
}

@Component注解在编译期生成的源码格式:
1,实现@Component注解的接口
2,静态内部类Builder,含有用于设置@Component注解中modules的方法
3,生成的Component类名为@Component注解的接口的简单名称加前缀Dagger。
4,一个接收builder的构造函数,保存相关的module。
5,实现@Component注解的接口中定义的方法

@Generated(
  value = "dagger.internal.codegen.ComponentProcessor",
  comments = "https://google.github.io/dagger"
)
public final class DaggerMyComponent implements MyComponent {
  private MyModule myModule;

  private DaggerMyComponent(Builder builder) {
    initialize(builder);
  }

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

  public static MyComponent create() {
    return new Builder().build();
  }

  @SuppressWarnings("unchecked")
  private void initialize(final Builder builder) {
    this.myModule = builder.myModule;
  }

  @Override
  public MyService myService() {
    return MyModule_ProvideMyServiceFactory.proxyProvideMyService(myModule);
  }

  public static final class Builder {
    private MyModule myModule;

    private Builder() {}

    public MyComponent build() {
      if (myModule == null) {
        this.myModule = new MyModule();
      }
      return new DaggerMyComponent(this);
    }

    public Builder myModule(MyModule myModule) {
      this.myModule = Preconditions.checkNotNull(myModule);
      return this;
    }
  }
}

@Inject

当@Inject标注在构造器时,说明该类的实例交由Dagger生成,Dagger会在编译期间生成一个XXX_Factory类。
当@Inject标注在字段上时,Dagger会在编译期生成一个XXX_MembersInjector类。

public class MapKeyDemo {


    @Inject
    Map map;

    private String param;
    @Inject
    public MapKeyDemo(String param){
        this.param=param;
    }

    public static void main(String [] args){
        MapKeyComponent mapKeyComponent=DaggerMapKeyComponent.create();
        MapKeyDemo mapKeyDemo=mapKeyComponent.mapKeyDemo();
        mapKeyComponent.inject(mapKeyDemo);
    }

}

生成的类


@Generated(
  value = "dagger.internal.codegen.ComponentProcessor",
  comments = "https://google.github.io/dagger"
)
public final class MapKeyDemo_Factory implements Factory {
  private final Provider paramProvider;

  private final Provider> mapProvider;

  public MapKeyDemo_Factory(
      Provider paramProvider, Provider> mapProvider) {
    this.paramProvider = paramProvider;
    this.mapProvider = mapProvider;
  }

  @Override
  public MapKeyDemo get() {
    return provideInstance(paramProvider, mapProvider);
  }

  public static MapKeyDemo provideInstance(
      Provider paramProvider, Provider> mapProvider) {
    MapKeyDemo instance = new MapKeyDemo(paramProvider.get());
    MapKeyDemo_MembersInjector.injectMap(instance, mapProvider.get());
    return instance;
  }

  public static MapKeyDemo_Factory create(
      Provider paramProvider, Provider> mapProvider) {
    return new MapKeyDemo_Factory(paramProvider, mapProvider);
  }

  public static MapKeyDemo newMapKeyDemo(String param) {
    return new MapKeyDemo(param);
  }
}

@Generated(
  value = "dagger.internal.codegen.ComponentProcessor",
  comments = "https://google.github.io/dagger"
)
public final class MapKeyDemo_MembersInjector implements MembersInjector {
  private final Provider> mapProvider;

  public MapKeyDemo_MembersInjector(Provider> mapProvider) {
    this.mapProvider = mapProvider;
  }

  public static MembersInjector create(Provider> mapProvider) {
    return new MapKeyDemo_MembersInjector(mapProvider);
  }

  @Override
  public void injectMembers(MapKeyDemo instance) {
    injectMap(instance, mapProvider.get());
  }

  public static void injectMap(MapKeyDemo instance, Map map) {
    instance.map = map;
  }
}

@Subcomponent

Subcomponent可以使用Component提供的依赖,因此一些公共的组件信息可以由Component提供。

Component和Module

@Module
public class MyModule {
    @Provides
    public MyService provideMyService(){
        return new MyService();
    }
}

@Component(modules = MyModule.class)
public interface MyComponent {
    //添加Subcomponent
    MySubComponent plus(MySubModule mySubModule);
}

Subcomponent和它的Module

@Module
public class MySubModule {
}
@Subcomponent(modules = MySubModule.class)
public interface MySubComponent {
    void inject(SubcomponentDemo demo);
}

注意MyService是在MyModule中提供的而不是MySubModule提供的
使用

public class SubcomponentDemo {

    @Inject
    MyService myService;

    SubcomponentDemo() {
    }
    public static void main(String[] args) {
       SubcomponentDemo demo = new SubcomponentDemo();
        DaggerMyComponent
                .builder()
                .build()
                .plus(new MySubModule())//向Component中添加SubComponent,并返回SubComponent
                .inject(demo);//注入依赖
        demo.myService.serve();//成功注入,说明subcomponent可以使用component提供依赖
    }
}

看一下生成的Component源码

public final class DaggerMyComponent implements MyComponent {
  private MyModule myModule;

  private DaggerMyComponent(Builder builder) {
    initialize(builder);
  }

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

  public static MyComponent create() {
    return new Builder().build();
  }

  @SuppressWarnings("unchecked")
  private void initialize(final Builder builder) {
    this.myModule = builder.myModule;
  }

  @Override
  public MySubComponent plus(MySubModule mySubModule) {
    return new MySubComponentImpl(mySubModule);
  }

  public static final class Builder {
    private MyModule myModule;

    private Builder() {}

    public MyComponent build() {
      if (myModule == null) {
        this.myModule = new MyModule();
      }
      return new DaggerMyComponent(this);
    }

    public Builder myModule(MyModule myModule) {
      this.myModule = Preconditions.checkNotNull(myModule);
      return this;
    }
  }
  /**
    * Subcomponent以内部类形式存在于Component类中
    */
  private final class MySubComponentImpl implements MySubComponent {
    private MySubComponentImpl(MySubModule mySubModule) {}

    @Override
    public void inject(SubcomponentDemo demo) {
      injectSubcomponentDemo(demo);
    }

    @CanIgnoreReturnValue
    private SubcomponentDemo injectSubcomponentDemo(SubcomponentDemo instance) {
      SubcomponentDemo_MembersInjector.injectMyService(
          instance,
          MyModule_ProvideMyServiceFactory.proxyProvideMyService(DaggerMyComponent.this.myModule));
      return instance;
    }
  }
}

可以看到 Subcomponent以内部类形式存在于Component类中

你可能感兴趣的:(Dagger中的注解)