上一篇記錄了如何使用Dagger秆吵,其中還漏了一些內(nèi)容淮椰,回頭再補(bǔ)。今天來(lái)看看Dagger在預(yù)編譯時(shí)期生成的輔助代碼纳寂,看看Dagger做依賴注入的實(shí)現(xiàn)原理是咋樣的主穗。
還是從上一篇中最簡(jiǎn)單的Sample開始。先看下代碼:
MainActivity:
public class MainActivity extends AppCompatActivity {
@Inject
UserModel user;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerUserComponent.builder()
.userModule(new UserModule())
.build()
.inject(this);
((TextView) findViewById(R.id.text_view)).setText("Name:" + user.getName() + "::Age:" + user.getAge());
}
}
UserModel:
public class UserModel {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
UserModule:
@Module
public class UserModule {
UserModule() {}
@Provides
UserModel provideUsers() {
UserModel user = new UserModel();
user.setName("lala");
user.setAge(18);
return user;
}
}
UserComponent:
@Component(modules = {UserModule.class})
public interface UserComponent {
void inject(MainActivity mainActivity);
}
運(yùn)行結(jié)果如下:
OK毙芜,咱們先來(lái)看看Dagger為我們上面的代碼生成了哪些東東忽媒。
咱們自己的類:
1.MainActivity
2.UserComponent
3.UserModel
4.UserModule
Dagger生成的類:
1.DaggerUserComponent
2.UserModule_ProvideUsersFactory
3.MainActivity_MembersInjector
好,下面來(lái)逐個(gè)看看這幾個(gè)生成類
直接從我們執(zhí)行注入的代碼下手:
DaggerUserComponent.builder()
.userModule(new UserModule())
.build()
.inject(this);
可以看到腋粥,我們通過Builder方式晦雨,傳一個(gè)UserModule的實(shí)例,build一個(gè)DaggerUserComponent的實(shí)例出來(lái)隘冲,然后調(diào)用 inject 方法執(zhí)行注入操作闹瞧。
下面嘍一眼DaggerUserComponent的代碼。
DaggerUserComponent:
@Generated("dagger.internal.codegen.ComponentProcessor")
public final class DaggerUserComponent implements UserComponent {
private Provider<UserModel> provideUsersProvider;
private MembersInjector<MainActivity> mainActivityMembersInjector;
private DaggerUserComponent(Builder builder) {
assert builder != null;
initialize(builder);
}
public static Builder builder() {
return new Builder();
}
public static UserComponent create() {
return builder().build();
}
private void initialize(final Builder builder) {
this.provideUsersProvider = UserModule_ProvideUsersFactory.create(builder.userModule);
this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUsersProvider);
}
@Override
public void inject(MainActivity mainActivity) {
mainActivityMembersInjector.injectMembers(mainActivity);
}
public static final class Builder {
private UserModule userModule;
private Builder() {
}
public UserComponent build() {
if (userModule == null) {
this.userModule = new UserModule();
}
return new DaggerUserComponent(this);
}
public Builder userModule(UserModule userModule) {
if (userModule == null) {
throw new NullPointerException("userModule");
}
this.userModule = userModule;
return this;
}
}
}
這個(gè)類非常簡(jiǎn)單展辞,它實(shí)現(xiàn)了咱們寫的UserComponent接口奥邮,實(shí)現(xiàn)了inject方法。重點(diǎn)在初始化 (initialize) 和注入 (inject) 兩個(gè)方法纵竖。
private Provider<UserModel> provideUsersProvider;
private MembersInjector<MainActivity> mainActivityMembersInjector;
private void initialize(final Builder builder) {
this.provideUsersProvider = UserModule_ProvideUsersFactory.create(builder.userModule);
this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUsersProvider);
}
可以看到漠烧,initialize這個(gè)方法創(chuàng)建了兩個(gè)成員變量杏愤,provideUsersProvider
和 mainActivityMembersInjector
。
創(chuàng)建Provider的代碼引出了第二個(gè)生成類: UserModule_ProvideUserFactory
@Generated("dagger.internal.codegen.ComponentProcessor")
public final class UserModule_ProvideUsersFactory implements Factory<UserModel> {
private final UserModule module;
public UserModule_ProvideUsersFactory(UserModule module) {
assert module != null;
this.module = module;
}
@Override
public UserModel get() {
UserModel provided = module.provideUsers();
if (provided == null) {
throw new NullPointerException("Cannot return null from a non-@Nullable @Provides method");
}
return provided;
}
public static Factory<UserModel> create(UserModule module) {
return new UserModule_ProvideUsersFactory(module);
}
}
顧名思義已脓,UserModule_ProvideUsersFactory 是一個(gè)工廠類珊楼,此類用來(lái)生產(chǎn)我們用 @Inject 注解的UserModel實(shí)例。
上面這句是屁話度液,UserModel的真正的實(shí)例并不在這里生產(chǎn)厕宗,可以看到,這個(gè)“偽工廠”接受一個(gè)咱們寫的UserModule的實(shí)例堕担,然后在get方法中調(diào)用UserModule的provideUsers()方法(咱們自己寫的)已慢,把拿到的UserModel實(shí)例返回。
咱們回到DaggerUserComponent霹购,再瞄一眼初始化的第一句代碼:
this.provideUsersProvider = UserModule_ProvideUsersFactory.create(builder.userModule);
在這里創(chuàng)建了一個(gè)生產(chǎn)UserModel實(shí)例的工廠實(shí)例佑惠。該實(shí)例的get方法返回一個(gè)UserModel的實(shí)例(從Module的provide方法中拿到的)。
OK齐疙,拿到了Provider的實(shí)例膜楷,來(lái)看看初始化的第二行代碼:
this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUsersProvider);
這里引出了第三個(gè)生成類宫患,MainActivity_MembersInjector.
@Generated("dagger.internal.codegen.ComponentProcessor")
public final class MainActivity_MembersInjector implements MembersInjector<MainActivity> {
private final MembersInjector<AppCompatActivity> supertypeInjector;
private final Provider<UserModel> userProvider;
public MainActivity_MembersInjector(MembersInjector<AppCompatActivity> supertypeInjector, Provider<UserModel> userProvider) {
assert supertypeInjector != null;
this.supertypeInjector = supertypeInjector;
assert userProvider != null;
this.userProvider = userProvider;
}
@Override
public void injectMembers(MainActivity instance) {
if (instance == null) {
throw new NullPointerException("Cannot inject members into a null reference");
}
supertypeInjector.injectMembers(instance);
instance.user = userProvider.get();
}
public static MembersInjector<MainActivity> create(MembersInjector<AppCompatActivity> supertypeInjector, Provider<UserModel> userProvider) {
return new MainActivity_MembersInjector(supertypeInjector, userProvider);
}
}
MainActivity_MembersInjector的create方法接收兩個(gè)參數(shù)挑围,生成一個(gè)實(shí)例返回。這個(gè)類實(shí)現(xiàn)了MembersInjector接口邓馒,實(shí)現(xiàn)了injectMembers方法轿塔,咦特愿?
instance.user = userProvider.get();
真相只有一個(gè),這一句才是真正執(zhí)行注入的代碼勾缭。從接收到的Provider實(shí)例中通過調(diào)用get方法拿到UserModel實(shí)例揍障,并賦給傳進(jìn)來(lái)的MainActivity實(shí)例的user成員變量。這也是為什么我們用 @Inject 注解的變量不可以是private的原因俩由。
所以這么看下來(lái)亚兄,注入過程還是很簡(jiǎn)單的,像很多文章說(shuō)的那樣采驻,There is no magic with Dagger.
就在飄飄然的時(shí)候,瞄見了這句代碼
supertypeInjector.injectMembers(instance);
supertypeInjector匈勋?這個(gè)是初始化的時(shí)候創(chuàng)建塞進(jìn)來(lái)的:
this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUsersProvider);
注意這里有兩個(gè)長(zhǎng)得很像的類礼旅,MembersInjector 和 MembersInjectors,臥槽洽洁。
MembersInjector是一個(gè)接口痘系,就是上面提到的那個(gè),里面只有一個(gè)injectMembers抽象方法饿自。那MembersInjectors是什么鬼...
public final class MembersInjectors {
/**
* Returns a {@link MembersInjector} implementation that injects no members
*
* <p>Note that there is no verification that the type being injected does not have {@link Inject}
* members, so care should be taken to ensure appropriate use.
*/
@SuppressWarnings("unchecked")
public static <T> MembersInjector<T> noOp() {
return (MembersInjector<T>) NoOpMembersInjector.INSTANCE;
}
private static enum NoOpMembersInjector implements MembersInjector<Object> {
INSTANCE;
@Override public void injectMembers(Object instance) {
if (instance == null) {
throw new NullPointerException();
}
}
}
/**
* Returns a {@link MembersInjector} that delegates to the {@link MembersInjector} of its
* supertype. This is useful for cases where a type is known not to have its own {@link Inject}
* members, but must still inject members on its supertype(s).
*
* <p>Note that there is no verification that the type being injected does not have {@link Inject}
* members, so care should be taken to ensure appropriate use.
*/
@SuppressWarnings("unchecked")
public static <T> MembersInjector<T> delegatingTo(MembersInjector<? super T> delegate) {
return (MembersInjector<T>) delegate;
}
private MembersInjectors() {}
}
初始化中調(diào)用的noOp方法返回一個(gè)NoOpMembersInjector枚舉類汰翠,這個(gè)類同樣實(shí)現(xiàn)了MembersInjector接口龄坪,在injectMembers方法中check了instance是否為null。
什么鬼复唤,在注入前不是已經(jīng)check過了么:
@Override
public void injectMembers(MainActivity instance) {
if (instance == null) {
throw new NullPointerException("Cannot inject members into a null reference");
}
supertypeInjector.injectMembers(instance);
instance.user = userProvider.get();
}
這個(gè)鬼地方先按下不表健田,因?yàn)槲乙膊技獚u,回頭再看看回來(lái)補(bǔ)上佛纫,現(xiàn)在看不懂為什么要連著check兩次妓局。
除了上面這個(gè)問題,對(duì)于Dagger依賴注入的流程應(yīng)該是比較清晰的呈宇。首先build一個(gè)DaggerUserComponent實(shí)例好爬,把Module傳進(jìn)去,再調(diào)它的inject方法甥啄,DaggerUserComponent的inject方法會(huì)調(diào)到MainActivityMembersInjector的injectMembers方法存炮,在這里執(zhí)行真正的注入。
以上是依賴注入一個(gè)實(shí)例時(shí)Dagger生成的輔助代碼蜈漓。如果我們給兩個(gè)成員注入穆桂,如下:
public class MainActivity extends AppCompatActivity {
@Inject
UserModel user1;
@Inject
UserModel user2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerUserComponent.builder()
.userModule(new UserModule())
.build()
.inject(this);
user2.setName("Arya Stark");
user2.setAge(12);
((TextView) findViewById(R.id.text_view_1)).setText("Name:" + user1.getName() + "::Age:" + user1.getAge());
((TextView) findViewById(R.id.text_view_2)).setText("Name:" + user2.getName() + "::Age:" + user2.getAge());
}
}
就不傳圖了,結(jié)果是兩個(gè)不一樣的TextView內(nèi)容迎变,因?yàn)檫@是兩個(gè)不同的實(shí)例充尉。
那么問題來(lái)了,那單例呢衣形?
還是用這個(gè)Sample驼侠,我給Component類和provide方法都加上 @Singleton 注解,最后的得到的結(jié)果就是單例谆吴,怎么做到的倒源?
對(duì)比了代碼后,我發(fā)現(xiàn)加Singleton注解和不加兩種情況下句狼,DaggerUserComponent的初始化代碼偷偷發(fā)生了變化笋熬。
不加 @Singleton 注解:
private void initialize(final Builder builder) {
this.provideUsersProvider = UserModule_ProvideUsersFactory.create(builder.userModule);
this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUsersProvider);
}
加 @Singleton注解:
private void initialize(final Builder builder) {
this.provideUsersProvider = ScopedProvider.create(UserModule_ProvideUsersFactory.create(builder.userModule));
this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUsersProvider);
}
看出區(qū)別了吧?不加注解的時(shí)候拿到的Provider是UserModule_ProvideUsersFactory的實(shí)例腻菇,加了注解后拿到的是ScopedProvider的實(shí)例胳螟。
好,來(lái)看看這個(gè)ScopedProvider.
/**
* A {@link Provider} implementation that memoizes the result of a {@link Factory} instance.
*
* @author Gregory Kick
* @since 2.0
*/
public final class ScopedProvider<T> implements Provider<T> {
private static final Object UNINITIALIZED = new Object();
private final Factory<T> factory;
private volatile Object instance = UNINITIALIZED;
private ScopedProvider(Factory<T> factory) {
assert factory != null;
this.factory = factory;
}
@SuppressWarnings("unchecked") // cast only happens when result comes from the factory
@Override
public T get() {
// double-check idiom from EJ2: Item 71
Object result = instance;
if (result == UNINITIALIZED) {
synchronized (this) {
result = instance;
if (result == UNINITIALIZED) {
instance = result = factory.get();
}
}
}
return (T) result;
}
/** Returns a new scoped provider for the given factory. */
public static <T> Provider<T> create(Factory<T> factory) {
if (factory == null) {
throw new NullPointerException();
}
return new ScopedProvider<T>(factory);
}
}
其實(shí)所謂的ScopedProvider就是把Factory包了一層筹吐,在里面存儲(chǔ)了Factory的實(shí)例糖耸。當(dāng)我們調(diào)用inject時(shí),DaggerUserComponent會(huì)把調(diào)用轉(zhuǎn)發(fā)給Provider丘薛,此時(shí)也就是ScopedProvider的get方法嘉竟,單例的關(guān)鍵就在這里。
這個(gè)類里定義了一個(gè)靜態(tài)常量UNINITIALIZED,第一次進(jìn)入get方法時(shí),會(huì)把現(xiàn)在還是靜態(tài)常量的instance賦給result局部變量舍扰。然后進(jìn)入判斷倦蚪,拿鎖,從factory實(shí)例中取出UserModel實(shí)例边苹,賦給instance和result陵且,然后把result返回。此時(shí)勾给,instance變量已經(jīng)變成了我們之前拿到的那個(gè)UserModel實(shí)例了滩报。后面再進(jìn)來(lái),局部變量result(之前的UserModel實(shí)例)和靜態(tài)常量不等播急,就再也進(jìn)不去判斷脓钾,直接返回instance,也就實(shí)現(xiàn)了單例桩警。
但是注意可训,這個(gè)單例是存在于DaggerUserComponent的實(shí)例中的,也就是說(shuō)捶枢,如果DaggerUserComponent產(chǎn)生了新的實(shí)例握截,那么也會(huì)產(chǎn)生新的UserModel實(shí)例。不能光說(shuō)不練烂叔,來(lái)做個(gè)實(shí)驗(yàn)谨胞。
對(duì)MainActivity做以下更改:
public class MainActivity extends AppCompatActivity {
@Inject
UserModel user1;
@Inject
UserModel user2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerUserComponent.builder()
.userModule(new UserModule())
.build()
.inject(this);
user2.setName("Arya Stark");
user2.setAge(12);
((TextView) findViewById(R.id.text_view_1)).setText("Name:" + user1.getName() + "::Age:" + user1.getAge());
((TextView) findViewById(R.id.text_view_2)).setText("Name:" + user2.getName() + "::Age:" + user2.getAge());
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
DaggerUserComponent.builder()
.userModule(new UserModule())
.build()
.inject(MainActivity.this);
((TextView) findViewById(R.id.text_view_1)).setText("Name:" + user1.getName() + "::Age:" + user1.getAge());
((TextView) findViewById(R.id.text_view_2)).setText("Name:" + user2.getName() + "::Age:" + user2.getAge());
}
}, 2000);
}
}
在第一次設(shè)置TextView的文字完了兩秒后,重新進(jìn)行一次注入蒜鸡,再更新TextView的顯示】枧現(xiàn)象就是,先顯示Arya Stark的信息逢防,兩秒后更新為十八歲的lala叶沛。因?yàn)榈诙巫⑷霑r(shí)生成了DaggerUserComponent的新實(shí)例,單例也就失效了忘朝。
自定義 @UserScope 注解
既然前面已經(jīng)把Dagger中的 @Singleton 的實(shí)現(xiàn)扒了個(gè)精光灰署,那么應(yīng)該很容易自定義Scope了。因?yàn)閱卫嬖谟赟copedProvider局嘁,而ScopedProvider是在Component中創(chuàng)建的溉箕,所以要自定義Scope,其實(shí)就是控制好Dagger給咱們生成的Component實(shí)現(xiàn)的生命周期悦昵。
哦對(duì)了约巷,先想想Scope是干啥的。我的理解是旱捧,保證某個(gè)類在一個(gè)時(shí)期中的實(shí)例的單一,也就是在定義的時(shí)期中是單例。比如我希望我們的CP項(xiàng)目Model在項(xiàng)目Activity中是單例枚赡,那么就可以定義一個(gè)ActivityScope氓癌,我希望我們的UserModel在用戶登陸后直到登出前是一個(gè)單例,那么就定義一個(gè)從登陸到登出的UserScope贫橙。
現(xiàn)在拓展一下我們的Sample. 在MainActivity之外贪婉,再創(chuàng)建SecondActivity和ThirdActivity,假設(shè)咱們的用戶在SecondActivity登錄卢肃,我們需要UserModel在SecondActivity到ThirdActivity之間是單例疲迂。
OK,既然UserScope跨Activity莫湘,那只能在比Activity更大的Scope下定義了尤蒿,這個(gè)Scope只能是整個(gè)App的ApplicationScope。
好吧幅垮,咱們還是按流程來(lái)腰池。先為整個(gè)App定義最大的Component:
@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {
UserComponent plus(UserModule userModule);
}
注解里標(biāo)識(shí)的AppModule:
@Module
public class AppModule {
private Application application;
public AppModule(Application application) {
this.application = application;
}
@Provides
public Application provideApplication() {
return application;
}
}
然后添加兩個(gè)Activity,SecondActivity和ThirdActivity忙芒,并為他們分別添加Component和Module示弓,代碼就不貼了。
這里咱們要用到一個(gè)叫做@Subcomponent的注解呵萨,它標(biāo)識(shí)子Component在父Component下進(jìn)行實(shí)現(xiàn)奏属,后面看了源碼就明白了,先記著潮峦。
@Subcomponent(modules = {SecondActivityModule.class})
public interface SecondActivityComponent {
SecondActivity inject(SecondActivity secondActivity);
}
@Subcomponent(modules = {ThirdActivityModule.class})
public interface ThirdActivityComponent {
ThirdActivity inject(ThirdActivity thirdActivity);
}
這兩個(gè)子Component的接口在inject方法中接收一個(gè)自己的Activity囱皿,然后返回去。
之后跑杭,添加一個(gè)Application的子類:
public class DaggerDemoApplication extends Application {
private AppComponent appComponent;
private UserComponent userComponent;
public static DaggerDemoApplication get(Context context) {
return (DaggerDemoApplication) context.getApplicationContext();
}
@Override
public void onCreate() {
super.onCreate();
initAppComponent();
}
private void initAppComponent() {
appComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this))
.build();
}
public UserComponent createUserComponent() {
userComponent = appComponent.plus(new UserModule());
return userComponent;
}
public void destroyUserComponent() {
userComponent = null;
}
public AppComponent getAppComponent() {
return appComponent;
}
public UserComponent getUserComponent() {
return userComponent;
}
}
注意铆帽,要在Manifest里頭為Application標(biāo)簽加上name屬性,name設(shè)為這個(gè)類名德谅。這樣爹橱,這個(gè)類就會(huì)在整個(gè)App啟動(dòng)的時(shí)候率先執(zhí)行。
就像前面說(shuō)的窄做,因?yàn)閁serScope跨Activity愧驱,所以要把它存在AppScope里頭,也就是說(shuō)當(dāng)UserScope開始時(shí)創(chuàng)建UserComponent的實(shí)現(xiàn)并存起來(lái)椭盏,當(dāng)UserScope結(jié)束的時(shí)候组砚,把UserComponent的實(shí)例釋放。所以在這里有create和destroy兩個(gè)方法掏颊,用于控制UserComponent的生命周期糟红。
創(chuàng)建UserScope注解:
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface UserScope {
}
現(xiàn)在更改一下Activity的內(nèi)容艾帐,把MainActivity的內(nèi)容更換成一個(gè)按鈕,用于開啟SecondActivity盆偿,在SecondActivity上添加兩個(gè)TextView和一個(gè)按鈕用于開啟ThirdActivity柒爸,ThirdActivity只有兩個(gè)TextView。
MainActivity:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this, SecondActivity.class));
}
});
}
}
public class SecondActivity extends AppCompatActivity {
@Inject
UserModel user;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
DaggerDemoApplication.get(this).createUserComponent();
DaggerDemoApplication.get(this)
.getUserComponent()
.plus(new SecondActivityModule())
.inject(this);
user.setName("Arya");
user.setAge(12);
((TextView) findViewById(R.id.text_view)).setText("Name:" + user.getName() + ":::Age:" + user.getAge());
findViewById(R.id.button_second).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(SecondActivity.this, ThirdActivity.class));
}
});
}
@Override
public void finish() {
DaggerDemoApplication.get(this).destroyUserComponent();
super.finish();
}
}
public class ThirdActivity extends AppCompatActivity {
@Inject
UserModel user;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_third);
DaggerDemoApplication.get(this)
.getUserComponent()
.plus(new ThirdActivityModule())
.inject(this);
((TextView) findViewById(R.id.text_view)).setText("Name:" + user.getName() + ":::Age:" + user.getAge());
}
}
運(yùn)行一下事扭。
可以看到捎稚,我在SecondActivity和ThirdActivity分別進(jìn)行了一次注入,只在SecondActivity更改了user的值求橄,結(jié)果在ThirdActivity中也生效了今野,說(shuō)明這個(gè)UserModel實(shí)例在SecondActivity和ThirdActivity之間是單例的存在。
下面咱來(lái)看看Dagger為咱們生成的代碼是怎么做到的罐农。
與之前不同条霜,Dagger在這里并沒有生成UserComponent實(shí)現(xiàn)的單獨(dú)類,而是將它作為DaggerAppComponent的內(nèi)部類啃匿。
@Generated("dagger.internal.codegen.ComponentProcessor")
public final class DaggerAppComponent implements AppComponent {
private DaggerAppComponent(Builder builder) {
assert builder != null;
}
public static Builder builder() {
return new Builder();
}
@Override
public UserComponent plus(UserModule userModule) {
return new UserComponentImpl(userModule);
}
public static final class Builder {
private AppModule appModule;
private Builder() {
}
public AppComponent build() {
if (appModule == null) {
throw new IllegalStateException("appModule must be set");
}
return new DaggerAppComponent(this);
}
public Builder appModule(AppModule appModule) {
if (appModule == null) {
throw new NullPointerException("appModule");
}
this.appModule = appModule;
return this;
}
}
private final class UserComponentImpl implements UserComponent {
private final UserModule userModule;
private Provider<UserModel> provideUsersProvider;
private UserComponentImpl(UserModule userModule) {
if (userModule == null) {
throw new NullPointerException();
}
this.userModule = userModule;
initialize();
}
private void initialize() {
this.provideUsersProvider = ScopedProvider.create(UserModule_ProvideUsersFactory.create(userModule));
}
@Override
public SecondActivityComponent plus(SecondActivityModule secondActivityModule) {
return new SecondActivityComponentImpl(secondActivityModule);
}
@Override
public ThirdActivityComponent plus(ThirdActivityModule thirdActivityModule) {
return new ThirdActivityComponentImpl(thirdActivityModule);
}
private final class SecondActivityComponentImpl implements SecondActivityComponent {
private final SecondActivityModule secondActivityModule;
private MembersInjector<SecondActivity> secondActivityMembersInjector;
private SecondActivityComponentImpl(SecondActivityModule secondActivityModule) {
if (secondActivityModule == null) {
throw new NullPointerException();
}
this.secondActivityModule = secondActivityModule;
initialize();
}
private void initialize() {
this.secondActivityMembersInjector = SecondActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), UserComponentImpl.this.provideUsersProvider);
}
@Override
public SecondActivity inject(SecondActivity secondActivity) {
secondActivityMembersInjector.injectMembers(secondActivity);
return secondActivity;
}
}
private final class ThirdActivityComponentImpl implements ThirdActivityComponent {
private final ThirdActivityModule thirdActivityModule;
private MembersInjector<ThirdActivity> thirdActivityMembersInjector;
private ThirdActivityComponentImpl(ThirdActivityModule thirdActivityModule) {
if (thirdActivityModule == null) {
throw new NullPointerException();
}
this.thirdActivityModule = thirdActivityModule;
initialize();
}
private void initialize() {
this.thirdActivityMembersInjector = ThirdActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), UserComponentImpl.this.provideUsersProvider);
}
@Override
public ThirdActivity inject(ThirdActivity thirdActivity) {
thirdActivityMembersInjector.injectMembers(thirdActivity);
return thirdActivity;
}
}
}
}
這個(gè)類相對(duì)比較長(zhǎng)蛔外,但是也不難理解∷萜梗可以看一眼我們是如何在DaggerDemoApplication中創(chuàng)建AppComponent和UserComponent的實(shí)現(xiàn)的夹厌。
private void initAppComponent() {
appComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this))
.build();
}
public UserComponent createUserComponent() {
userComponent = appComponent.plus(new UserModule());
return userComponent;
}
父Component AppComponent實(shí)現(xiàn)的創(chuàng)建與之前無(wú)異,使用它的Builder裆悄,傳一個(gè)AppModule實(shí)例再build矛纹。而作為子Component的UserComponent的創(chuàng)建就不同了。這里調(diào)用AppComponent的plus方法光稼,這個(gè)方法是我們定義的接口或南,接收一個(gè)UserModule實(shí)例,返回UserComponent.
在我們調(diào)用plus的時(shí)候艾君,創(chuàng)建了UserComponentImpl實(shí)例并返回采够。在這個(gè)內(nèi)部類中也有兩個(gè)我們定義的接口方法,分別接收自己Activity的Module冰垄,然后返回自己Activity的Component蹬癌,在這里又分別創(chuàng)建了SecondActivityComponentImpl和ThirdActivityComponentImpl實(shí)例。
再進(jìn)到這兩個(gè)內(nèi)部類中可以看到虹茶,真正的注入方法在這里逝薪。
@Override
public SecondActivity inject(SecondActivity secondActivity) {
secondActivityMembersInjector.injectMembers(secondActivity);
return secondActivity;
}
注意,這里的secondActivityMembersInjector在SecondActivityComponentImpl的初始化方法中創(chuàng)建:
private void initialize() {
this.secondActivityMembersInjector = SecondActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), UserComponentImpl.this.provideUsersProvider);
}
而provider是在UserComponentImpl中的初始化方法中創(chuàng)建的:
private void initialize() {
this.provideUsersProvider = ScopedProvider.create(UserModule_ProvideUsersFactory.create(userModule));
}
剩下的注入流程和之前的就一樣了蝴罪。inject方法中調(diào)用SecondActivity_MembersInjector的injectMembers方法董济,在這里通過調(diào)用Provider的get方法,由provider決定是否需要新建實(shí)例要门,需要時(shí)再調(diào)到咱們的provide方法拿到真正的實(shí)例并返回虏肾,不需要時(shí)直接返回廓啊。
以上是對(duì)使用 @SubComponent 注解實(shí)現(xiàn)自定義Scope的源碼解析。