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>