Dagger2源码分析

发布时间:2023年12月18日

首先,还是看看简单的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;
  }
  • 二,module创建

改造代码如下

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;
    }

这样就完成了整个调用过程

  • 3,局部作用域代

改造代码

@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方法。

文章来源:https://blog.csdn.net/luck_xiang/article/details/135045742
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。