6.基于Dagger2.38.1的hilt源码-AliasOfProcessor 和 DefineComponentProcessor

228 阅读3分钟

前言

AliasOfProcessor处理@AliasOf,该注解用于修饰其他注解。

DefineComponentProcessor处理@DefineComponent注解和@DefineComponent.Builder注解修饰的节点。

AliasOfProcessor 校验并且执行AliasOfPropagatedDataGenerator

规则

  1. @AliasOf必须和@Scope放在一起使用;
  • @Scope也是用于修饰注解的注解,表示范围;

AliasOfPropagatedDataGenerator生成代码

生成的代码存储在dagger.hilt.processor.internal.aliasof.codegen包下。

//This class should only be referenced by generated code!
//This class aggregates information across multiple compilations.
@AliasOfPropagatedData(defineComponentScope = @AliasOf注解的value值.class,alias = @AliasOf修饰的注解.class)
@Generated("AliasOfPropagatedDataGenerator")
public class $CLASS(全路径以"_"拼接){}

DefineComponentProcessor

DefineComponentProcessor用于处理@DefineComponent注解和@DefineComponent.Builder注解。

处理@DefineComponent注解

校验并生成DefineComponentMetadata对象

@DefineComponent修饰的节点我们称之为component节点;

校验规则:

  1. @DefineComponent#parent()生层次遍历,不能出现循环节点;

  2. @DefineComponent只能修饰接口;

  3. @DefineComponent修饰的接口不能继承别的接口;

  4. @DefineComponent修饰的接口不能使用泛型;

  5. @DefineComponent修饰的接口中如果存在方法,则必须是static修饰;

  6. @DefineComponent修饰的接口不可以使用@AliasOf注解修饰;

  7. @DefineComponent#parent中的节点类型不能是error,应该是正常的类或接口;

  8. @DefineComponent#parent中的节点类型默认是DefineComponentNoParent类;如果不是,则必须是使用@DefineComponent修饰的接口;

  9. @DefineComponent#parent中的节点使用了@DefineComponent修饰 || 当前component节点就是SingletonComponent接口;

  10. component节点可以是dagger.hilt.components包下的SingletonComponent接口,但是绝对不可以是其他包下的SingletonComponent类或接口;

DefineComponentMetadata对象属性:

  1. TypeElement component: @DefineComponent修饰的节点,

  2. ImmutableList scopes:收集component节点上使用@Scope修饰的注解修饰,

  3. Optional<DefineComponentMetadatas.DefineComponentMetadata> parentMetadata:@DefineComponent#parent中的节点如果也是用了@DefineComponent修饰,生成的对象;

处理@DefineComponent.Builder注解

@DefineComponent.Builder修饰的节点我们称之为builder节点

校验并生成DefineComponentBuilderMetadata对象

校验规则如下:

  1. builder节点必须是接口;

  2. builder接口不允许继承其他接口;

  3. builder接口不允许使用泛型;

  4. builder接口中如果存在变量,那么该变量必须使用static修饰;

  5. builder接口必须存在有且仅有非static修饰的无参方法(build方法);并且该build方法返回类型是使用@DefineComponent修饰的接口;

  6. builder接口中的方法要么是build方法,要么方法返回类型是builder接口类型,要么是返回类型是Builder接口的方法,要么是static修饰的方法;

生成DefineComponentBuilderMetadata对象属性:

  1. TypeElement builder:@DefineComponent.Builder修饰的接口,

  2. ExecutableElement buildMethod:builder方法-非static、无参、返回类型是@DefineComponent修饰的接口,

  3. DefineComponentMetadatas.DefineComponentMetadata componentMetadata:@DefineComponent修饰的接口生成的对象,自行查看上面。

@DefineComponent注解和@DefineComponent.Builder注解生成类

这里针对的是hilt中的源码生成类,下图没有截全,比较简单,可自行理解。

在这里插入图片描述

总结

我们一定要清楚当前源码中有哪些使用了@DefineComponent或@DefineComponent.Builder修饰,这个非常重要,后面会用到。

  1. SingletonComponent

     @Singleton
     @DefineComponent
     public interface SingletonComponent {}
    
  2. FragmentComponent

     @FragmentScoped
     @DefineComponent(parent = ActivityComponent.class)
     public interface FragmentComponent {
     }
    
  3. ActivityComponent

     @ActivityScoped
     @DefineComponent(parent = ActivityRetainedComponent.class)
     public interface ActivityComponent {}
    
  4. ActivityRetainedComponent

     @ActivityRetainedScoped
     @DefineComponent(parent = SingletonComponent.class)
     public interface ActivityRetainedComponent {}
    
  5. ServiceComponent

     @ServiceScoped
     @DefineComponent(parent = SingletonComponent.class)
     public interface ServiceComponent {}
    
  6. ViewComponent

     @ViewScoped
     @DefineComponent(parent = ActivityComponent.class)
     public interface ViewComponent {}
    
  7. ViewModelComponent

     @ViewModelScoped
     @DefineComponent(parent = ActivityRetainedComponent.class)
     public interface ViewModelComponent {}
    
  8. ViewWithFragmentComponent

     @ViewScoped
     @DefineComponent(parent = FragmentComponent.class)
     public interface ViewWithFragmentComponent {}
    
  9. ActivityComponentBuilder

     @DefineComponent.Builder
     public interface ActivityComponentBuilder {
         ActivityComponentBuilder activity(
                 @BindsInstance
                         Activity activity);
     
         ActivityComponent build();
     }
    
  10. ActivityRetainedComponentBuilder

    @DefineComponent.Builder
    public interface ActivityRetainedComponentBuilder {
        ActivityRetainedComponent build();
    }
    
  11. FragmentComponentBuilder

    @DefineComponent.Builder
    public interface FragmentComponentBuilder {
        FragmentComponentBuilder fragment(@BindsInstance Fragment fragment);
        FragmentComponent build();
    }
    
  12. ServiceComponentBuilder

    @DefineComponent.Builder
    public interface ServiceComponentBuilder {
        ServiceComponentBuilder service(@BindsInstance Service service);
        ServiceComponent build();
    }
    
  13. ViewComponentBuilder

    @DefineComponent.Builder
    public interface ViewComponentBuilder {
        ViewComponentBuilder view(@BindsInstance View view);
    
        ViewComponent build();
    
    }
    
  14. ViewModelComponentBuilder

    @DefineComponent.Builder
    public interface ViewModelComponentBuilder {
        ViewModelComponentBuilder savedStateHandle(@BindsInstance SavedStateHandle handle);
    
        ViewModelComponent build();
    }
    
  15. ViewWithFragmentComponentBuilder

    @DefineComponent.Builder
    public interface ViewWithFragmentComponentBuilder {
        ViewWithFragmentComponentBuilder view(@BindsInstance View view);
    
        ViewWithFragmentComponent build();
    }