美文网首页Android开发Android技术知识Android开发经验谈
[Android 学习笔记] Dragger2 依赖注入由浅入深

[Android 学习笔记] Dragger2 依赖注入由浅入深

作者: afluy | 来源:发表于2018-05-26 19:30 被阅读23次

    有参构造函数的类的依赖注入

    上篇博客中定义的 UserServer 类很简单, 只有一个无参构造函数, 但当它中定义了有参构造函数时, 要在哪里构造 UserServer 对象, 构造函数的参数有从哪里来?

    public class UserServer {
        private String name;
    
        public UserServer(String name) {
            this.name = name;
        }
    }
    

    Dragger2 库为了解决这个问题引入了 @Module 和 @Provides 注解,
    @Module 标识提供依赖的组件类, @Provides 标识提供依赖的方法.
    在 Demo 中新建一个 UserServerModule 类:

    import dagger.Module;
    import dagger.Provides;
    
    @Module
    public class UserServerModule {
    
        @Provides
        UserServer provideUserServer() {
            return new UserServer("kimi");
        }
    }
    

    同时也要在 SimpleActivityComponent 中指定通过 UserServerModule 来获取 UserServer 对象:

    import dagger.Component;
    
    @Component(modules = UserServerModule.class) // 指定 UserServerModule 类
    public interface SimpleActivityComponent {
        void inject(SimpleActivity activity);
    }
    
    

    编译后在 build 目录中生成一个 UserServerModule_ProvideUserServerFactory 类, 用于调用 UserServerModule 类的 provideUserServer 方法来生成 UserServer 对象:

    import dagger.internal.Factory;
    import dagger.internal.Preconditions;
    
    public final class UserServerModule_ProvideUserServerFactory implements Factory<UserServer> {
      private final UserServerModule module;
    
      public UserServerModule_ProvideUserServerFactory(UserServerModule module) {
        this.module = module;
      }
    
      @Override
      public UserServer get() {
        return provideInstance(module);
      }
    
      public static UserServer provideInstance(UserServerModule module) {
        return proxyProvideUserServer(module);
      }
    
      public static UserServerModule_ProvideUserServerFactory create(UserServerModule module) {
        return new UserServerModule_ProvideUserServerFactory(module);
      }
    
      // 核心方法, 调用 instance.provideUserServer() 获取 UserServer 对象
      public static UserServer proxyProvideUserServer(UserServerModule instance) {
        return Preconditions.checkNotNull(
            instance.provideUserServer(), "Cannot return null from a non-@Nullable @Provides method");
      }
    }
    

    同时编译后 DaggerSimpleActivityComponent 也发生了变更:

    import dagger.internal.Preconditions;
    
    public final class DaggerSimpleActivityComponent implements SimpleActivityComponent {
      private UserServerModule userServerModule;
    
      private DaggerSimpleActivityComponent(Builder builder) {
        initialize(builder);
      }
    
      public static Builder builder() {
        return new Builder();
      }
    
      public static SimpleActivityComponent create() {
        return new Builder().build();
      }
    
      @SuppressWarnings("unchecked")
      private void initialize(final Builder builder) {
        this.userServerModule = builder.userServerModule;
      }
    
      @Override
      public void inject(SimpleActivity activity) {
        injectSimpleActivity(activity);
      }
    
    // 通过 UserServerModule_ProvideUserServerFactor.proxyProvideUserServer 方法调用 userServerModule 对象中的 provideUserServer 方法来获取 UserServer 对象
      private SimpleActivity injectSimpleActivity(SimpleActivity instance) {
        SimpleActivity_MembersInjector.injectServer(
            instance,
            UserServerModule_ProvideUserServerFactory.proxyProvideUserServer(userServerModule)); 
        return instance;
      }
    
      public static final class Builder {
        private UserServerModule userServerModule;
    
        private Builder() {}
    
         // 直接new 一个 UserServerModule 对象
        public SimpleActivityComponent build() {
          if (userServerModule == null) {
            this.userServerModule = new UserServerModule();
          }
          return new DaggerSimpleActivityComponent(this);
        }
    
        public Builder userServerModule(UserServerModule userServerModule) {
          this.userServerModule = Preconditions.checkNotNull(userServerModule);
          return this;
        }
      }
    }
    

    DaggerSimpleActivityComponent 的主要变更就是在 injectSimpleActivity 方法中通过 UserServerModule_ProvideUserServerFactory 类来获取 UserServer 对象, 而上一篇博客中是直接 new 了一个 UserServer 对象:

      private SimpleActivity injectSimpleActivity(SimpleActivity instance) {
        SimpleActivity_MembersInjector.injectServer(instance, new UserServer());
        return instance;
      }
    

    所以 UserServer 对象的初始化的责任被间接的分配到我们定义的 UserServerModule 类去实现.
    所以当需要注入的对象是要用有参构造函数来构造, 就可以用 @Module 和 @Provides 注解定义一个类来提供要注入对象, 然后再 Component 中添加对 Module 类的引用:

    @Component(modules = UserServerModule.class) // 指定 UserServerModule 类
    

    依赖注入的局限

    当前是在 UserServerModule 中写死的构造函数的参数, 但是如果 UserServer 对象的构造是需要 SimpleActivity 类传参数怎么办? 这个问题这么回答吧:

    一个类不应该知道如何实现依赖注入, 也就是说只有当前类依赖被注入的对象, 反之则不可, 当前类不应该参与到被注入类的初始化过程. 所以如果你有一个对象需要当前类去传参来构造, 那么就不应该用依赖注入, 直接在当前类实现中手动 new 对象就可以了.

    相关文章

      网友评论

        本文标题:[Android 学习笔记] Dragger2 依赖注入由浅入深

        本文链接:https://www.haomeiwen.com/subject/pmnmjftx.html