(1)依赖注入概念
依赖注入未来单说就是非本身主动初始化依赖,而经过外部来传入依赖的方式,咱们就称为依赖注。举例来讲:以下面的代码所示,A是依赖注入的例子,B是非依赖注入的例子。汽车(Car)依赖轮胎(Tyre)的资源。android
【A:依赖注入的例子】git
public class Car { ... // 轮胎 Tyre tyre; ... public Car(Tyre tyre) { this.tyre = tyre; } }
【B:非依赖注入的例子】github
public class Car{ ... // 轮胎 Tyre tyre; ... public Car(Tyre tyre) { this.tyre = new Tyre(); } }
(2)Ioc容器:负责依赖注入控制器
如A所示,上文已经说了Car的实现依赖于外界传入的Tyre。那么负责传入这个资源的角色就是Ioc容器。Ioc容器自己也不实际产生资源,它会请求其余的对象来生成资源。由此来看,Car解除了和Tyre的依赖,而和Ioc产生了依赖:Car->Ioc容器。这样的好处是,若是Car依赖于多个对象(方向盘,轮胎,地盘等等),那么Car没必要要和那么多对象产生直接的依赖,而只须要依赖Ico容器便可。无论Car须要什么资源,它只须要找Ico容器要便可。由此能够看出,依赖注入就是要解决对象之间的依赖关系,即由对象->对象的直接依赖,转化到对象->Ico的依赖。app
<img src="https://img-blog.csdn.net/201...; width="60%">框架
(3)依赖注入的好处ide
在Java里面,存在大量的依赖注入的框架,如Spring等等。在Dagger2出来以前,Android也存在一些依赖注入框架如Dagger1。其均是依靠反射来实现依赖注入,所以会带来必定的性能问题,所以这些框架并无在Android中流行起来。函数
Dagger2经过APT技术,经过在编译的时候生成注入的工厂类代码,解决了性能问题,所以Dagger2开始在Android上发扬光大。源码分析
Dagger2实现原理如C图所示,其主要由三部分组成性能
【C:dagger2实现原理】
<img src="https://img-blog.csdn.net/201...; width="60%">单元测试
总结起来就是,当被注入的对象须要Component去给他设置属性的时候,Component就会去找它的Module去生成该对象。若是Module完成不了这件事情,Component就会去找它依赖的Component(Dependency Component)去给他生成该对象。Dependency Component自己也没有生成对象能力,其就依赖它的Module去生成该对象
在了解Dagger2注解以前咱们首先记住2个东西:
- Dagger2全部对象匹配都是按照返回类型来匹配,与函数命名无关
- Dagger2的Scope的大小都是咱们人为赋予的,Scope的大小不是名字决定的,而是Component之间的依赖关系决定的。
在2.1中所提的三种角色都是经过注解来完成的,dagger2经常使用注解以下:
(1)Component使用的注解
@Component
- 做用对象:Class - 代表该class是个Component
@Scope
- 做用对象:Class - 指明Component 范围,其依赖的Model若是用@Scope修饰,必须与Component 的Scope相同
Component示例以下所示:
@BigScoped @Component(modules = {ActivityModule.class},dependencies = {AppComponent.class}) public interface ActivityComponent { void inject(Dagger2Activity dagger2Activity); ActivityScopeObj activityScopeObj(); ActivityObj activityObj(); }
(2)Module使用的注解
@Module
- 做用对象:Class - 代表该Class是个对象的生成器
@Provider
- 做用对象:Method - 代表该方法能对外提供对象:**按照返回的类型匹配**
@Scope
- 做用对象:Method - 代表该方法在Scope范围内是个单例
Module示例:
@Module public class ActivityModule { @Provides public ActivityObj provideActivityObj() { return new ActivityObj(); } @Provides public FragmentNotVisibleObj provideActivityNotVisibleObj() { return new FragmentNotVisibleObj(); } @BigScoped @Provides public ActivityScopeObj provideActivityScopeObj() { return new ActivityScopeObj(); } }
(3)被注入对象使用的注解
@Inject
- 做用对象:Field - 代表该属性依赖Component进行注入
代码示例:
public class Dagger2Activity extends AppCompatActivity implements ActivityDataProvider { @Inject ActivityObj mActivityObj; @Inject FragmentNotVisibleObj mActivityNotVisibleObj; @Inject ActivityScopeObj mActivityScopeObj; ActivityComponent component = DaggerActivityComponent.builder() .activityModule(new ActivityModule()) .build(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_dagger2_test); // 使用component来给Dagger2Activity的属性赋值 component.inject(this);
再看看ActivityComponent生命的inject方法
public interface ActivityComponent { void inject(Dagger2Activity dagger2Activity);
案例地址:dagger案例源码
// BigScope @Documented @Scope @Retention(RetentionPolicy.RUNTIME) public @interface BigScoped { } // SmallScope @Documented @Scope @Retention(RetentionPolicy.RUNTIME) public @interface SmallScoped { }
(1)Dagger2Activity
public class Dagger2Activity extends AppCompatActivity implements ActivityDataProvider { @Inject ActivityObj mActivityObj; @Inject FragmentNotVisibleObj mActivityNotVisibleObj; @Inject ActivityScopeObj mActivityScopeObj; ActivityComponent component = DaggerActivityComponent.builder() .activityModule(new ActivityModule()) .build(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_dagger2_test); // 使用component来给Dagger2Activity的属性赋值 component.inject(this); Dagger2Fragment dagger2Fragment = new Dagger2Fragment(); dagger2Fragment.setDataProvider(this); getFragmentManager().beginTransaction() .addToBackStack(null) .replace(R.id.container, dagger2Fragment) .commit(); } @Override public ActivityComponent getComponent() { return component; } @Override public ActivityScopeObj getActivityScopeObj() { return mActivityScopeObj; } }
(2)ActivityComponent
@BigScoped @Component(modules = {ActivityModule.class},dependencies = {AppComponent.class}) public interface ActivityComponent { // 暴露接口给Dagger2Activity,让其传入本身,好给Dagger2Activity属性赋值 void inject(Dagger2Activity dagger2Activity); // 暴露给其余Component的接口,只有暴露的接口,其余的Component才能够依赖于它建立对象,按照返回类型匹配,与函数名无关 ActivityScopeObj activityScopeObj(); ActivityObj activityObj(); }
(3)ActivityModule
@Module public class ActivityModule { @Provides public ActivityObj provideActivityObj() { return new ActivityObj(); } @Provides public FragmentNotVisibleObj provideActivityNotVisibleObj() { return new FragmentNotVisibleObj(); } @BigScoped @Provides public ActivityScopeObj provideActivityScopeObj() { return new ActivityScopeObj(); } }
【Dagger2Activity的总体注入过程以下图】
从图中能够看出dagger2的实现模型和上面介绍的Ioc控制反转模型表现一致
(1)Dagger2Fragment
须要注入三个对象
- mActivityObj由ActivityComponent生成 - mActivityScopeObj由ActivityComponent生成 - mFragmentObj有FragmentComponent生成 - 其余参见注释
public class Dagger2Fragment extends android.app.Fragment { ActivityDataProvider mProvider; @Inject ActivityObj mActivityObj; @Inject ActivityScopeObj mActivityScopeObj; @Inject FragmentObj mFragmentObj; @Override public View onCreateView(LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.dagger2_fragment, container, false); FragmentComponent component = DaggerFragmentComponent.builder() .fragmentModule(new FragmentModule()) // 依赖于ActivityComponent,是由Activity传进来的,所以次数使用的activityComponent和Dagger2Activity使用的Component是同一个对象 // 所以 mActivityScopeObj和mProvider.getActivityScopeObj()获得的是同一个对象 .activityComponent(mProvider.getComponent()) .build(); component.inject(this); // true Logger.d("ActivityScope single instance:" + (mActivityScopeObj == mProvider.getActivityScopeObj())); // false Logger.d("not Scope Object:" + (mActivityObj == mFragmentObj.mActivityObj)); return view; } public void setDataProvider(ActivityDataProvider provider) { mProvider = provider; } }
(2)FragmentComponent
@Component(modules = {FragmentModule.class},dependencies = {ActivityComponent.class}) @SmallScoped public interface FragmentComponent { void inject(Dagger2Fragment dagger2Fragment); }
(3)FragmentObj
public class FragmentObj { @Inject ActivityObj mActivityObj; // 用@Inject修饰构造和在Module用@Provide修饰等价 @Inject public FragmentObj() { } }
(1)查找对象按照什么匹配?
按照类型匹配
@Module public class ActivityModule { @Provides public ActivityObj provideActivityObj() { return new ActivityObj(); } @Provides public ActivityObj ActivityObj() { return new ActivityObj(); }
(2)Scope之间的依赖关系怎么肯定?
按照其修饰的Component间的依赖关系决定,仍是上面的例子:
@Component(modules = {FragmentModule.class},dependencies = {ActivityComponent.class}) @SmallScoped public interface FragmentComponent { void inject(Dagger2Fragment dagger2Fragment); } @BigScoped @Component(modules = {ActivityModule.class},dependencies = {AppComponent.class}) public interface ActivityComponent { void inject(Dagger2Activity dagger2Activity); ActivityScopeObj activityScopeObj(); ActivityObj activityObj(); }
由于FragmentComponent-->ActivityComponent。所以,能够得出ActivityComponent实例生命周期长于FragmentComponent的实例(否则,FragmentComponent要传入AppComponent依赖的时候,没有能够赋的值),所以能够得出SmallScope和BiggerScope之间存在以下关系。
<img src="https://img-blog.csdn.net/201...; width="70%">
(3)其余更多工程上使用的问题能够参见ppt:dagger2源码分析