介紹
關於dagger github上是這樣介紹的。
A fast dependency injector for Android and Java. Android和Java的快速依賴注入器。
栗子
dagger2有很多用法,本文用最一個簡單的使用方法所生成的原始碼來進行剖析。首先把我們的栗子程式碼貼出來:
public class Persion {
public void sayHello(){
System.out.println("hello");
}
}
@Module
public class PersionModule {
@Provides
public Persion providePersion(){
return new Persion();
}
}
@Component(modules = PersionModule.class)
public interface HelloActivityComponent {
void inject(HelloDaggerActivity activity);
}
public class HelloDaggerActivity extends Activity {
@Inject
Persion mPersion;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DaggerHelloActivityComponent.create().inject(this);
setContentView(R.layout.activity_hello);
mPersion.sayHello();
}
}
複製程式碼
原始碼簡析
接下來編譯,來看apt生成的三個檔案:
我們從DaggerHelloActivityComponent.create().inject(this);
注入依賴的方法口入開始分析。DaggerHelloActivityComponent程式碼如下:
public final class DaggerHelloActivityComponent implements HelloActivityComponent {
private PersionModule persionModule;
private DaggerHelloActivityComponent(Builder builder) {
initialize(builder); //4
}
public static Builder builder() {
return new Builder();
}
public static HelloActivityComponent create() {
return new Builder().build(); //1
}
@SuppressWarnings("unchecked")
private void initialize(final Builder builder) {
this.persionModule = builder.persionModule; //5
}
@Override
public void inject(HelloDaggerActivity activity) {
injectHelloDaggerActivity(activity);//6
}
private HelloDaggerActivity injectHelloDaggerActivity(HelloDaggerActivity instance) {
HelloDaggerActivity_MembersInjector.injectMPersion(//7
instance,
Preconditions.checkNotNull(
persionModule.providePersion(),
"Cannot return null from a non-@Nullable @Provides method"));
return instance;
}
public static final class Builder {
private PersionModule persionModule;
private Builder() {}
public HelloActivityComponent build() {
if (persionModule == null) {
this.persionModule = new PersionModule();//2
}
return new DaggerHelloActivityComponent(this);//3
}
public Builder persionModule(PersionModule persionModule) {
this.persionModule = Preconditions.checkNotNull(persionModule);
return this;
}
}
}
複製程式碼
註釋1create方法呼叫了new Builder().build();
這個建造者方法。註釋2中可以看到這個建造者方法建立了我們提供的PersionModule類的物件,並在註釋3中返回了DaggerHelloActivityComponent
類物件傳入了當前builder物件。註釋4的構造方法執行了initialize ()
初始化方法,然後在註釋5中初始化了module物件為builder中建立的module物件。接下來執行註釋6inject()
然後執行到到註釋7injectHelloDaggerActivity()
方法HelloDaggerActivity_MembersInjector.injectMPersion( instance, Preconditions.checkNotNull( persionModule.providePersion(), "Cannot return null from a non-@Nullable @Provides method"));
此處執行HelloDaggerActivity_MembersInjector.injectMPersion ()
方法,傳入了兩個引數,一個instance我們的需要被注入依賴的目標類HelloDaggerActivity物件,另外一個是persionModule.providePersion()
方法也就是我們編寫的PersionModule類返回new Persion()
。
貼上HelloDaggerActivity_MembersInjector類原始碼如下:
public final class HelloDaggerActivity_MembersInjector
implements MembersInjector<HelloDaggerActivity> {
private final Provider<Persion> mPersionProvider;
public HelloDaggerActivity_MembersInjector(Provider<Persion> mPersionProvider) {
this.mPersionProvider = mPersionProvider;
}
public static MembersInjector<HelloDaggerActivity> create(Provider<Persion> mPersionProvider) {
return new HelloDaggerActivity_MembersInjector(mPersionProvider);
}
@Override
public void injectMembers(HelloDaggerActivity instance) {
injectMPersion(instance, mPersionProvider.get());
}
public static void injectMPersion(HelloDaggerActivity instance, Persion mPersion) {
instance.mPersion = mPersion; //1
}
}
複製程式碼
此處註釋1中將persion物件設定到activity中。至此我們HelloDaggerActivity所依賴的mPersion物件就注入到了目標類HelloDaggerActivity中。終於可以愉快的玩耍了~~~