目录
一:dagger2的好处or用途
1.1 一切都是为了解耦
1.2 增加开发效率
1.3 更好的管理类实例
二 原理分析
参考文章:
一切都是为了解耦。
一个类的new代码是非常可能充斥在app的多个类中的,假如该类的构造函数发生变化,那这些涉及到的类都得进行修改。设计模式中提倡把容易变化的部分封装起来。
我们用了dagger2后,假如是通过用Inject注解标注的构造函数创建类实例,则即使构造函数变的天花乱坠,我们基本上都不需要修改任何代码。假如是通过工厂模式Module创建类实例,Module其实就是把new类实例的代码封装起来,这样即使类的构造函数发生变化,只需要修改Module即可。
我认为如果是小app一般没必要用到Daggger2(为了学习还是好的),解耦也是要付出相应的空间和时间代价的,工作量和复杂度都可能会提高(多人协作大项目会提高你的效率),编译时也容易出错,但在解耦数据和业务逻辑方面,Dagger2无愧利器之名。
这里的开发效率着重于:省去重复而又无意义new实例对象代码。当然这也会增加我们一些依赖包括module、component等代码的铺垫,但做完这些铺垫,dagger2就可以把new一个实例的工作做了,从而让开发者把精力集中在业务上。
一个很棒的例子就是Dagger2中单例的写法,开发者不需要担心自己写的单例方法是否线程安全,懒汉or饿汉模式,这些Dagger2都会帮你搞定。
每个app中的ApplicationComponent管理整个app的全局类实例,所有的全局类实例都统一交给ApplicationComponent管理,并且它们的生命周期与app的生命周期一样。
每个页面对应自己的Component,页面Component管理着自己页面所依赖的所有类实例。因为Component,Module,整个app的类实例结构变的很清晰。
在大体介绍完 Dagger2 后,我们分析一下实现原理。
以《Dagger2利器系列一:入门到使用》中最简单的 案例A:入门demo为例,Dagger2 在编译时根据注解生成一些辅助类,我们具体分析下生成的辅助类。辅助类可以通过 DaggerXXXComponent 来快速定位。上面两个例子对应生成辅助类如下:
我们分析下具体的注入过程,首先 Car 中会调用DaggerCarComponent.builder().build().inject(this);,我们来看下 DaggerCarComponent 的源码:
public final class DaggerCarComponent implements CarComponent {
private DaggerCarComponent() {
}
public static Builder builder() {
return new Builder();
}
public static CarComponent create() {
return new Builder().build();
}
@Override
public void inject(Car car) {
injectCar(car);}
private Car injectCar(Car instance) {
Car_MembersInjector.injectEngine(instance, new Engine());
return instance;
}
public static final class Builder {
private Builder() {
}
public CarComponent build() {
return new DaggerCarComponent();
}
}
}
可以看到,DaggerCarComponent 是CarComponent的实现类,最终调用到了inject方法里的injectCar方法,然后调用了injectCar方法里的 Car_MembersInjector.injectEngine(instance, new Engine());
我们来看下Car_MembersInjector的源码:
public final class Car_MembersInjector implements MembersInjector {
private final Provider engineProvider;
public Car_MembersInjector(Provider engineProvider) {
this.engineProvider = engineProvider;
}
public static MembersInjector create(Provider engineProvider) {
return new Car_MembersInjector(engineProvider);}
@Override
public void injectMembers(Car instance) {
injectEngine(instance, engineProvider.get());
}
@InjectedFieldSignature("com.ysalliance.getfan.daggertest.Car.engine")
public static void injectEngine(Car instance, Engine engine) {
instance.engine = engine;
}
}
可以看到,这是Car对应的@Inject。
Engine_Factory对应的源码:
public final class Engine_Factory implements Factory {
@Override
public Engine get() {
return newInstance();
}
public static Engine_Factory create() {
return InstanceHolder.INSTANCE;
}
public static Engine newInstance() {
return new Engine();
}
private static final class InstanceHolder {
private static final Engine_Factory INSTANCE = new Engine_Factory();
}
}
可以看到,Engine_Factory,是Engine构造方法的@Inject。
上面是最简单的Dagger2的注入原理的分析,如果想看带@Module 和 @Provides的稍微复杂一点的Dagger2的注入原理,推荐看这一篇博文:《Dagger2 使用及原理分析》,相信在这篇的基础上,学习带@Module 和 @Provides的注入原理,更加水到渠成。
dagger2到底有哪些好处?
关于Android Dagger2 应用的疑惑?