Dagger2源码分析-最简单的注入过程

rrmr1339 8年前
   <p><img src="https://simg.open-open.com/show/a2f035d3545b00de9844a10cca435068.png"></p>    <p style="text-align:center">Dagger要实现的类以及APT生成的类</p>    <h2><strong>Dagger2最简单的依赖注入实践</strong></h2>    <p>要实现三个类:</p>    <ol>     <li>Dagger2Activity</li>     <li>ActivityComponent</li>     <li>ActivityModule</li>    </ol>    <p>直接上代码:</p>    <p>1、Dagger2Activity</p>    <pre>  <code class="language-java">public class Dagger2Activity extends Activity {        private ActivityComponent mActivityComponent;        @Inject      UserModel mUserModel;        @Bind(R.id.tv_user_id)      TextView tvUserId;      @Bind(R.id.tv_user_name)      TextView tvUserName;      @Bind(R.id.tv_user_gender)      TextView tvUserGender;        @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.ex_dagger2_activity);          ButterKnife.bind(this);            mActivityComponent = DaggerActivityComponent.builder().activityModule(new ActivityModule(1, "Leon", 1)).build();          mActivityComponent.inject(this);            tvUserId.setText(mUserModel.id + "");          tvUserName.setText(mUserModel.name);          tvUserGender.setText(mUserModel.gender + "");      }  }</code></pre>    <p>2、ActivityComponent</p>    <pre>  <code class="language-java">@Component(modules = ActivityModule.class)  public interface ActivityComponent {        void inject(Dagger2Activity activity);  }</code></pre>    <p>3、ActivityModule</p>    <pre>  <code class="language-java">@Module  public class ActivityModule {        private UserModel mUserModel;        public ActivityModule(long userId, String userName, int gender) {          mUserModel = new UserModel(userId, userName, gender);      }        @Provides      UserModel provideUserModel() {          return mUserModel;      }  }</code></pre>    <h2><strong>列出所有类</strong></h2>    <p>使用Dagger,要实现</p>    <p>Dagger2Activity 、 ActivityComponent 、 ActivityModule</p>    <p>三个类,Make Project之后生成三个类:</p>    <ul>     <li>DaggerActivityComponent</li>     <li>Dagger2Activity_MemberInject</li>     <li>ActivityModule_ProviderUserModelFactory</li>    </ul>    <h2><strong>分析代码</strong></h2>    <p>注入程序的入口</p>    <pre>  <code class="language-java">mActivityComponent.inject(this);</code></pre>    <pre>  <code class="language-java">@Component(modules = ActivityModule.class)  public interface ActivityComponent {        void inject(ExDagger2Activity activity);  }</code></pre>    <p>直接调用的是ActivityComponent的inject。ActivityComponent是个接口,实现类是DaggerActivityComponent。</p>    <pre>  <code class="language-java">@Override    public void inject(ExDagger2Activity activity) {      exDagger2ActivityMembersInjector.injectMembers(activity);    }</code></pre>    <p>注意,inject接收被注入的实例参数。接下来的 <strong>DaggerActivityComponent的注入工作</strong> 应该是:</p>    <ul>     <li>找到被注入的Activity中被@Inject注解的成员mUserModel变量;</li>     <li><strong>然后赋值给mUserModel</strong></li>    </ul>    <p>DaggerActivityComponent有两个成员变量:</p>    <pre>  <code class="language-java">private Provider<UserModel> provideUserModelProvider;//负责提供对象  private MembersInjector<ExDagger2Activity> dagger2ActivityMembersInjector;//负责给被@Inject的成员变量赋值</code></pre>    <p>赋值给被@Inject的成员变量</p>    <p>DaggerActivityComponent的inject调用的是dagger2ActivityMembersInjector的injectMembers,实现如下:</p>    <p>Dagger2Activity_MembersInjector.java</p>    <pre>  <code class="language-java">@Override    public void injectMembers(ExDagger2Activity instance) {      if (instance == null) {        throw new NullPointerException("Cannot inject members into a null reference");      }      instance.mUserModel = mUserModelProvider.get();    }</code></pre>    <p>从mUserModelProvider中获取对象赋值给被注入类Dagger2Activity的mUserModel成员变量(所以,mUserModel必须是public的)。</p>    <p>mUserModelProvider从哪里来的?</p>    <p>DaggerActivityComponent.java</p>    <pre>  <code class="language-java">private void initialize(final Builder builder) {        this.provideUserModelProvider =          ActivityModule_ProvideUserModelFactory.create(builder.activityModule);        this.exDagger2ActivityMembersInjector =          ExDagger2Activity_MembersInjector.create(provideUserModelProvider);    }</code></pre>    <p>DaggerActivityComponent初始化他的两个成员变量时,传入的。也就是说,赋值提供对象的是provideUserModelProvider(看名字也知道了)。</p>    <p>轮到ActivityModule发挥作用了:创建对象</p>    <p>ActivityModule生成了一个工厂类ActivityModule_ProvideUserModelFactory。这个工厂类是专门生产UserModel对象的。</p>    <pre>  <code class="language-java">@Module  public class ActivityModule {        private UserModel mUserModel;        public ActivityModule(long userId, String userName, int gender) {          mUserModel = new UserModel(userId, userName, gender);      }        @Provides      UserModel provideUserModel() {          return mUserModel;      }  }    @Generated(    value = "dagger.internal.codegen.ComponentProcessor",    comments = "https://google.github.io/dagger"  )  public final class ActivityModule_ProvideUserModelFactory implements Factory<UserModel> {    private final ActivityModule module;      public ActivityModule_ProvideUserModelFactory(ActivityModule module) {      assert module != null;      this.module = module;    }      @Override    public UserModel get() {      return Preconditions.checkNotNull(          module.provideUserModel(), "Cannot return null from a non-@Nullable @Provides method");    }      public static Factory<UserModel> create(ActivityModule module) {      return new ActivityModule_ProvideUserModelFactory(module);    }  }</code></pre>    <p>放在一起对比。ActivityModule的provideUserModel方法创建了对象,被ActivityModule_ProvideUserModelFactory的get方法获取。</p>    <h2><strong>总结</strong></h2>    <p>分析完代码之后,再看看文章开头的类图。Make Project之后生产三个类的作用分别是:</p>    <ul>     <li>DaggerActivityComponent:程序入口,负责串联创建对象与赋值。</li>     <li>Dagger2Activity_MemberInject:持有被注入的对象DaggerActivity,赋值给被@Inject的成员变量。</li>     <li>ActivityModule_ProviderUserModelFactory:创建对象。</li>    </ul>    <p> </p>    <p>来自:http://www.jianshu.com/p/14841af5b462</p>    <p> </p>