注解自动生成dagger2 Component组件的工具

自己通过apt写的一个自动生成Component组件的注解工具,主要具有以下功能:

  • 生成Component组件,可指定一个或多个Module,可指定scope,并可以添加子组件(SubComponent)

  • 生成子组件SubComponent,并可指定Module,scope,父组件和子组件

  • 自动在组件中提供出子组件,并提供inject方法

  • 还能根据生成的组件,生成DaggerHelper帮助类,更方便的注入

注解种类:

  • GenRootComponent(int tag,int childTag,modules,scope)
    该注解用在哪个类上,就根据该类生成代码
    生成的Component被@Component注解
    参数含义:
    -tag 是自己的标识,tag一致的Component为同一组(主要用于父组件查找子组件,不填默认为0)
    -childTag 是子组件标识,工具会通过该标识来查找所有tag和此标识相等的SubComponent,并在本Component中提供出来
    -modules 该组件对应的Module(必填,一个或多个)
    -scope 该组件对应的scope(选填)
@GenRootComponent(scope = Singleton.class, modules = {AppModule.class}, tag = 10, childTag = 11)
public class App extends Application {
}

生成的代码

@Component(
    modules = AppModule.class
)
@Singleton
public abstract interface AppComponent extends MembersInjector<App> {
  BaseActivityComponent.Builder providerBaseActivityComponent();

  @Component.Builder
  abstract interface Builder {
    AppComponent build();

    Builder setModule(AppModule module);
  }
}
  • GenSubComponent(int tag,int childTag,modules,scope)
    该注解用在哪个类上,就根据该类生成代码
    生成的Component被@Subcomponent注解
    生成的Subcomponent依然可以有子组件注解
    参数含义:
    -tag 是自己的标识,tag一致的Component为同一组(主要用于父组件查找子组件,不填默认为0)
    -childTag 是子组件标识,工具会通过该标识来查找所有tag和此标识相等的SubComponent,并在本Component中提供出来
    -modules 该组件对应的Module(必填,一个或多个)
    -scope 该组件对应的scope(选填)
@GenSubComponent(modules = ActivityModule.class, tag = 12)
public class MainActivity extends BaseActivity {
}

生成的代码

@Subcomponent(
    modules = ActivityModule.class
)
public abstract interface MainActivityComponent extends 
//提供子组件
MembersInjector<MainActivity> {
  @Subcomponent.Builder
  abstract interface Builder {
    MainActivityComponent build();

    Builder setModule(ActivityModule module);
  }
}

  • @GenInheritedSubComponent(int tag,int childTag,modules,scope)
    有时可能需要在基类中注入需要的对象,这样的话,每一个该基类的实现类都需要生成Component,并注入该实现类,才能保证基类中的对象不为空,有时并不是每个Activity或Fragment都需要自己的Component,这时就可以用该注解,该注解适合使用在基类中,生成基类的Component,如果某一个实现类不需要Component,就可以使用基类的Component,并且通过该注解生成的Component,会提供所有没有自己的Component的实现类的inject()方法来注入自己(该步骤可在基类中完成)
    其他功能与GenSubComponent一致

参数含义:
-tag 是自己的标识,tag一致的Component为同一组(主要用于父组件查找子组件,不填默认为0)
-childTag 是子组件标识,工具会通过该标识来查找所有tag和此标识相等的SubComponent,并在本Component中提供出来
-modules 该组件对应的Module(必填,一个或多个)
-scope 该组件对应的scope(选填)

@GenInheritedSubComponent(tag = 11, childTag = 12, modules = BaseModule.class, scope = BaseScope.class,shouldInject = false)
public class BaseActivity extends AppCompatActivity

生成的代码

@Subcomponent(
    modules = BaseModule.class
)
@BaseScope
public abstract interface BaseActivityComponent {
//该Activity没有自己的Component,则提供注入方法
  void injectMembers(AppActivity target);

  SplashActivityComponent.Builder providerSplashActivityComponent();

  MainActivityComponent.Builder providerMainActivityComponent();

  @Subcomponent.Builder
  abstract interface Builder {
    BaseActivityComponent build();

    Builder setModule(BaseModule module);
  }
}
  • @GenDaggerHelper
    功能

  • 通过该注解,可以生成DaggerHelper辅助类(单例)提供注入方法

  • 该注解可使用在任何一个类上(主要为了提供一个包来存放该辅助类)

  • 生成的注入方法时分层级的,就是说,必须先注入该组件的父组件,才能注入该组件,不然会空指针(因为父组件还没获取到)

  • @GenInheritedSubComponent注解的基类的子类(没有自己的Component的子类)统一提供一个注入方法,会根据传入的类型,自动找到inject()方法来注入(也就是说可以在基类中注入)

  • 生成的注入方法对应的Module构造函数若有参数,则注入时也需要传入对应的参数

具体来看生产代码

public class DaggerHelper {
  public AppComponent appcomponent;

  private BaseActivityComponent baseactivitycomponent;

  private DaggerHelper() {
  }

  public static DaggerHelper getInstance() {
    return Holder.INSTANCE;
  }

  public AppComponent getAppComponent(App target, Application param0) {
    appcomponent = DaggerAppComponent.builder().setModule(new AppModule(param0)).build();
    appcomponent.injectMembers(target);
    return appcomponent;
  }

//因BaseModule()有参数,所以这里也需要传参(param0)
  public BaseActivityComponent getBaseActivityComponent(Object target, Activity param0) {
    baseactivitycomponent = appcomponent.providerBaseActivityComponent().setModule(new BaseModule(param0)).build();
    if(target instanceof AppActivity) {
      AppActivity appactivity = (AppActivity)target;
      baseactivitycomponent.injectMembers(appactivity);
    }
    return baseactivitycomponent;
  }

  public MainActivityComponent getMainActivityComponent(MainActivity target, Activity param0) {
    MainActivityComponent mainactivitycomponent = baseactivitycomponent.providerMainActivityComponent().setModule(new ActivityModule(param0)).build();
    mainactivitycomponent.injectMembers(target);
    return mainactivitycomponent;
  }

  public SplashActivityComponent getSplashActivityComponent(SplashActivity target) {
    SplashActivityComponent splashactivitycomponent = baseactivitycomponent.providerSplashActivityComponent().setModule(new SpashModule()).build();
    splashactivitycomponent.injectMembers(target);
    return splashactivitycomponent;
  }

  private static class Holder {
    private static final DaggerHelper INSTANCE = new DaggerHelper();
  }
}

库的介绍就到这里了,希望对大家有所帮助!!!

下面是项目地址:
注:项目中还有两个其他的注解工具,以后有时间再介绍

gradle:

 compile "com.suhang.lazy:lazyannotation_annotation:1.1.8"
 compile "com.suhang.lazy:lazyannotation:1.1.8"
 annotationProcessor "com.suhang.lazy:lazyannotation_compiler:1.1.8"

https://github.com/lightofrain/LazyAnnotation.git

推荐阅读更多精彩内容