(6) Dagger2 @Module analysis 4

Code example
class Food {
    
    
}
class Tiger {
    
    
    // 假如老虎需要食物
    Food food;
    public Tiger(Food food) {
    
    
        this.food = food;
    }
    public void sleep() {
    
    
        System.out.println("Tiger sleeping");
    }
}

// 为注射器提供工厂类
// @Module: 表示Dagger2可以将该类当作对象工厂.
@Module
class ZooModule {
    
    
    private Food food;
    public ZooModule(Food food) {
    
    
        this.food = food;
    }
    // @Provides: 表示Dagger2可以调用providerTiger(Food food)方法为注射器提供对象.
    @Provides
    public Tiger providerTiger() {
    
    
        return new Tiger(food);
    }
}
// 对象使用者
public class Zoo {
    
    
    // @Inject: 该注解用于成员变量上代表注射器可以为该成员变量赋值对象.
    @Inject
    Tiger tiger;

    @Test
    public void 案例六() {
    
    
        // ZooModule中的成员food无法通过Dagger2自动生成,需要用户手动创建.
        DaggerZooComponent.builder().zooModule(new ZooModule(new Food())).build().inject(this);
        tiger.sleep();
    }
}
// 注射器
// @Component: 该注解是用来创造对象提供方和对象使用间的桥梁,如何将对象赋值给使用者的成员变量都是由它来做的.
@Component(modules = {
    
    ZooModule.class})
interface ZooComponent {
    
    
    Zoo inject(Zoo zoo);
}
Dagger2 generated code reading

The main analysis is that Module depends on an object that cannot be created with Dagger2. How to add the object to the injector?
Similar situations are very common. For example, Activity is created by the system. If a Module depends on Activity objects, how does Dagger2 handle their dependencies? .

Looking at the code generated by Degger2 based on the above case, the generated code is in the build\generated\sources\annotationProcessor\..folder.

  1. DaggerZooComponent.builder().zooModule(new ZooModule(new Food())).build()
    Create an DaggerZooComponentobject, here is zooModule(new ZooModule(new Food()))how to deal with it.
final class DaggerZooComponent implements ZooComponent {
    
    
    // 工厂对象
    private final ZooModule zooModule;
    // DaggerZooComponent构造方法
    private DaggerZooComponent(ZooModule zooModuleParam) {
    
    
        this.zooModule = zooModuleParam;
    }
    public static Builder builder() {
    
    
        // 创建DaggerZooComponent.Builder对象
        return new Builder();
    }
    static final class Builder {
    
    
        private ZooModule zooModule;
        private Builder() {
    
    
        }
        // 创建ZooModule对象
        public Builder zooModule(ZooModule zooModule) {
    
    
          this.zooModule = Preconditions.checkNotNull(zooModule);
          return this;
        }
        public ZooComponent build() {
    
    
          Preconditions.checkBuilderRequirement(zooModule, ZooModule.class);
          // 创建DaggerZooComponent对象,它持有ZooModule引用
          return new DaggerZooComponent(zooModule);
        }
    }
}
  1. .inject(this)Object injection
    Use DaggerZooComponentobjects to inject the Dagger2created Tigerobjects into Zooit.
final class DaggerZooComponent implements ZooComponent {
    
    
    // 接口中的方法,由DaggerZooComponent实现,该方法就是用来向Zoo对象中注入Tiger对象的.
    @Override
    public Zoo inject(Zoo zoo) {
    
    
        // zoo就是inject(this)中的this了,代表Zoo对象.
        return injectZoo(zoo);
    }
    private Zoo injectZoo(Zoo instance) {
    
    
        // 1. ZooModule_ProviderTigerFactory.providerTiger(zooModule): 通过ZooModule工厂获取Zoo需要的Tiger对象.
        // 2. Zoo_MembersInjector.injectTiger(instance, getTiger()): 这里就是为Zoo对象中所需字段赋值.
        Zoo_MembersInjector.injectTiger(instance, ZooModule_ProviderTigerFactory.providerTiger(zooModule));
        return instance;
    }
}
  1. ZooModule_ProviderTigerFactory.providerTiger(zooModule)
public final class ZooModule_ProviderTigerFactory implements Factory<Tiger> {
    
    
    public static Tiger providerTiger(ZooModule instance) {
    
    
      // providerTiger()为用户在ZooModule中实现的方法,用来返回Tiger对象.
      return Preconditions.checkNotNull(instance.providerTiger(), "Cannot return null from a non-@Nullable @Provides method");
    }
}
  1. Assignment
    Zoo_MembersInjector.injectTiger(instance, ZooModule_ProviderTigerFactory.providerTiger(zooModule));
public final class Zoo_MembersInjector implements MembersInjector<Zoo> {
    
    
   public static void injectTiger(Zoo instance, Object tiger) {
    
    
     instance.tiger = (Tiger) tiger;
   } 
}

If you Footcan't Dagger2add it to the syringe by creating it yourself, you can manually create an Footobject, then pass Modulethe object into it through construction Module, and then hand it over to the Modulefactory method for use.

Guess you like

Origin blog.csdn.net/MoLiao2046/article/details/106884514