首先,还是看看简单的dagger为我们写了哪些代码,先看代码
public class User {
@Inject
public User() {
Log.e("User", "new User " + this);
}
}
@Component
public interface AppComponent {
void inject(MainActivity mainActivity);
}
public class MainActivity extends ComponentActivity {
//需要注入的实例化类
@Inject
User user;
@Inject
User userhttps://img-home.csdnimg.cn/images/20230724024https%3A%2F%2Fimg-home.csdnimg.cn%2Fimages%2F20230724024159.png%3Forigin_url%3D1%26pos_id%3DNFOdz3Wp59.png?origin_url=https%3A%2F%2Fimg-home.csdnimg.cn%2Fimages%2F20230724024159.png%3Forigin_url%3D1%26pos_id%3DNFOdz3Wp&pos_id=NFOdz3Wp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e("MainActivity", "MainActivity new onCreate");
DaggerAppComponent.create().inject(this);
}
}
打印如下
这里生成了两个对象,我们看看Dagger为我们做了什么,dagger生成了如下三个类
我们从注入入口开始看
DaggerAppComponent.create().inject(this);
这里调用了DaggerAppComponent这类
调用inject执行代码如下
@Override
public void inject(MainActivity mainActivity) {
injectMainActivity(mainActivity);
}
//对inject方法传入的类进行赋值
private MainActivity injectMainActivity(MainActivity instance) {
MainActivity_MembersInjector.injectUser(instance, new User());
MainActivity_MembersInjector.injectUser1(instance, new User());
return instance;
}
这里可以看到new? User() 执行了两次,所以创建了两个对象 ,先一步我们看看injectUser做了啥
MainActivity_MembersInjector
//直接MainActivity对象里面的变了进行赋值对进行赋值,这里是直接调用对应对象进行复制,你会发现,如果将对象写成privated
//的,就会赋值失败,所以要注入的对象不能是private的,如果是private的对象可以在其set方法上进行注入,列入
//@Inject setUser(User user);
@InjectedFieldSignature("com.kx.dagger.MainActivity.user")
public static void injectUser(MainActivity instance, User user) {
instance.user = user;
}
改造代码如下
public class User {
public User() {
Log.e("User", "new User " + this);
}
}
@Module
public class UserModule {
@Provides
User privodeUser() {
return new User();
}
}
@Component(modules = {UserModule.class})
public interface AppComponent {
void inject(MainActivity mainActivity);
}
执行代码打印
?打印和前面一样,我们看看dagger做了什么,下面是生成的代码
生成的类还是和前面一样,我们从inject开始看,代码调用流程如下
1,DaggerAppComponent
@Override
public void inject(MainActivity mainActivity) {
injectMainActivity(mainActivity);
}
private MainActivity injectMainActivity(MainActivity instance) {
MainActivity_MembersInjector.injectUser(instance, UserModule_PrivodeUserFactory.privodeUser(userModule));
MainActivity_MembersInjector.injectUser1(instance, UserModule_PrivodeUserFactory.privodeUser(userModule));
return instance;
}
2,UserModule_PrivodeUserFactory
public static User privodeUser(UserModule instance) {
return Preconditions.checkNotNullFromProvides(instance.privodeUser());
}
3,UserModule
@Provides
User privodeUser() {
return new User();
}
那么UserModule这个类是在那里创建的呢
1,DaggerAppComponent
public AppComponent build() {
if (userModule == null) {
this.userModule = new UserModule();
}
return new AppComponentImpl(userModule);
}
2,DaggerAppComponent.AppComponentImpl
private AppComponentImpl(UserModule userModuleParam) {
this.userModule = userModuleParam;
}
这样就完成了整个调用过程
改造代码
@Module
public class UserModule {
@Singleton
@Provides
User privodeUser() {
return new User();
}
}
@Singleton
@Component(modules = {UserModule.class})
public interface AppComponent {
void inject(MainActivity mainActivity);
}
打印如下
1,首先看create()方法干了 啥
DaggerAppComponent.create()
public static AppComponent create() {
return new Builder().build();
}
DaggerAppComponent Builder build()
public AppComponent build() {
if (userModule == null) {
//每次调用create都会创建这些对象
this.userModule = new UserModule();
}
return new AppComponentImpl(userModule);
}
?
DaggerAppComponent AppComponentImpl
private AppComponentImpl(UserModule userModuleParam) {
initialize(userModuleParam);
}
private void initialize(final UserModule userModuleParam) {
//每次调用create,这个类都会重新创建,所以,只要调用一次create,然后其余所有直接用inject注入,就//能实现全局单利,想要把这些类都变成单利
this.privodeUserProvider = DoubleCheck.provider(UserModule_PrivodeUserFactory.create(userModuleParam));
}
整个流程就是初始化了一个?Provider<User> privodeUserProvider
2,Provider<User> privodeUserProvider如何创建
private void initialize(final UserModule userModuleParam) {
this.privodeUserProvider = DoubleCheck.provider(UserModule_PrivodeUserFactory.create(userModuleParam));
}
2.1,创建 UserModule_PrivodeUserFactory对象
serModule_PrivodeUserFactory.create(userModuleParam)
?该对象实现了Factory<User>,该接口是一个空实现
serModule_PrivodeUserFactory implements Factory<User>
接下来看看DoubleCheck.privider干了啥
public static <P extends Provider<T>, T> Provider<T> provider(P delegate) {
//判空,抛异常
checkNotNull(delegate);
//如果传入的对象已经是子类直接返回
if (delegate instanceof DoubleCheck) {
return delegate;
}
//否则创建
return new DoubleCheck<T>(delegate);
}
private DoubleCheck(Provider<T> provider) {
assert provider != null;
this.provider = provider;
}
3,inject执行
@Override
public void inject(MainActivity mainActivity) {
injectMainActivity(mainActivity);
}
private MainActivity injectMainActivity(MainActivity instance) {
MainActivity_MembersInjector.injectUser(instance, privodeUserProvider.get());
MainActivity_MembersInjector.injectUser1(instance, privodeUserProvider.get());
return instance;
}
这里主要的重点就是privodeUserProvider.get(),我们看看这个get方法干了啥,前面的代码可以看出这个是个DoubleCheck<T> 类,那我们就看这个类的get方法
//这个就是我们单利的写法,双重判定
public T get() {
Object result = instance;
//第一次进来,这里肯定为true
if (result == UNINITIALIZED) {
//加锁,这里只能同时执行一个
synchronized (this) {
result = instance;
//这里一定为true
if (result == UNINITIALIZED) {
//这里实例化传入的是UserModule_PrivodeUserFactory这个类调用了这个的get,这里这个get之调用了一次
result = provider.get();
instance = reentrantCheck(instance, result);
/* Null out the reference to the provider. We are never going to need it again, so we
* can make it eligible for GC. */
provider = null;
}
}
}
//整个代码就是一个单利模式,这里返回的永远只有一个对象
return (T) result;
}
调用了 UserModule_PrivodeUserFactory这个类的get方法
public User get() {
return privodeUser(module);
}
public static User privodeUser(UserModule instance) {
return Preconditions.checkNotNullFromProvides(instance.privodeUser());
}
}
到这里之调用了一次UserModule privodeUser(),所以只创建了一次,所以在同一个类是局部单利
修改源代码
public class DaggerApplication extends Application {
private final static AppComponent appComponent=DaggerAppComponent.create();
public static AppComponent getAppComponent() {
return appComponent;
}
}
public class MainActivity extends ComponentActivity {
//需要注入的实例化类
@Inject
User user;
@Inject
User user1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e("MainActivity", "MainActivity new onCreate");
DaggerApplication.getAppComponent().inject(this);
startActivity(new Intent(this,MainActivity2.class));
}
}
public class MainActivity2 extends AppCompatActivity {
//需要注入的实例化类
@Inject
User user;
@Inject
User user1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main4);
Log.e("MainActivity", "MainActivity2 new onCreate");
DaggerApplication.getAppComponent().inject(this);
}
}
代码打印如下
这里代码的差距就是,之前是在每个类上面都执行了一个create(),会多次调用前面create方法,就会多次创建里面所有相关的对象,现在将这个类的create()写到了Application中了,这个create()就只调用了一次,那么对应的对象也就只创建了一下,所以后面注入的对象都都只有一个,这样就变成了单利模式了。这里把create方法放所以地方都可以,只要在整个app里面,只调用了一次create方法,就只会创建一个对象,变成全局单利
接着改造代码
public class DaggerSingleton {
private final static AppComponent appComponent=DaggerAppComponent.create();
public static AppComponent getAppComponent() {
return appComponent;
}
}
public class MainActivity extends ComponentActivity {
//需要注入的实例化类
@Inject
User user;
@Inject
User user1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e("MainActivity", "MainActivity new onCreate");
DaggerSingleton.getAppComponent().inject(this);
startActivity(new Intent(this,MainActivity2.class));
}
}
public class MainActivity2 extends AppCompatActivity {
//需要注入的实例化类
@Inject
User user;
@Inject
User user1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main4);
Log.e("MainActivity", "MainActivity2 new onCreate");
DaggerSingleton.getAppComponent().inject(this);
}
}
打印代码如下,依然是单利
Dagger全局单利和局部单利只有一个差距,就是create创建的次数,create这个方法是初始化module里面所有参数的,指定作用域后调用这个方法就只会创建一次所有module的类,dagger的作用域最主要就是理解DoubleCheck中的get方法。