1,简介
不像Spring框架那样通过反射完成IOC、DI、AOP功能,Dagger仅仅完成IOC,DI过程,实现原理是动态生成代码;Dagger通过注解完成注入,常用注解有以下:
@Module,依赖提供方;
@Component,提供方与注入方之间纽带;
@Inject,如果注解在构造函数中,属于提供方,否则为注入方;
@Singleton,单例模式;
@Provider,与@Module连用,依赖提供方;
@Scope,自定义注解使用,参考@Singleton
2,注入流程图
3,简单实例
(1)创建依赖提供方,对象A和B;
package com.zjw.myblog.dagger;
import com.zjw.myblog.dagger.domain.A;
import com.zjw.myblog.dagger.domain.B;
import dagger.Module;
import dagger.Provides;
@Module
public class MainModule {
@Provides
A providerA(){
return new A();
}
@Provides
B providerB(){
return new B();
}
}
(2)创建Component,理解为Injector;
import dagger.Component;
//指定注入方为MainModule
@Component(modules = {MainModule.class})
public interface MainComponent {
//注意,这里注入的类不能是jar包里的
void inject(DevJavaActivity1 activity);
void inject(MainApplication application);
}
(3)此后,rebuild下工程,在out目录下会自动生成Dagger代码,注意使用包名在dagger下,
(4)在Component指定的inject类中完成依赖注入,此例在Application.onCreate方法中进行;
public class MainApplication extends Application {
public static final String TAG = "MainApplication";
@Inject
Lazy<A> mA;
//Lazy,懒加载模式,使用时才注入
@Inject
Lazy<B> mB;
@Override
public void onCreate() {
super.onCreate();
//工厂模式,构造者模式,获取component实例,可以理解为提供者与注入方之间的纽带
MainComponent component = DaggerMainComponent.builder().build();
//注入此处,这会遍历注解有@injiect的方法,然后动态生成代码,完成依赖注入,显然不能private
component.inject(this);
Log.d(TAG, "inject -> " + mA.get());
Log.d(TAG, "inject -> " + mB.get());
}
}
日志记录如下,这便完成一次简单的注入过程;
4,进阶知识
(1)Lazy和Provider模式,前者使用才注入,后者每次都强行注入新的对象;
@Inject
Lazy<A> mA;
@Inject
Provides<B> mB;
(2)多个@Provider返回同一对象时,使用@Name区分,
@Provides
@Named("selectA")
A providerA(){
return new A();
}
@Provides
@Named("selectA2")
A providerA2(){
return new A();
}
(3)@Module详解,
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Module {
/**
* Additional {@code @Module}-annotated classes from which this module is
* composed. The de-duplicated contributions of the modules in
* {@code includes}, and of their inclusions recursively, are all contributed
* to the object graph.
*/
Class<?>[] includes() default {};
/**
* Any {@link Subcomponent}- or {@code @ProductionSubcomponent}-annotated classes which should be
* children of the component in which this module is installed. A subcomponent may be listed in
* more than one module in a component.
*
* @since 2.7
*/
@Beta
Class<?>[] subcomponents() default {};
}
include不必多说,引用其它模块,参与此次注入提供方;
subcomponents为子模块,后面讨论;
(4)@Component详解,
@Retention(RUNTIME) // Allows runtimes to have specialized behavior interoperating with Dagger.
@Target(TYPE)
@Documented
public @interface Component {
/**
* A list of classes annotated with {@link Module} whose bindings are used to generate the
* component implementation. Note that through the use of {@link Module#includes} the full set of
* modules used to implement the component may include more modules that just those listed here.
*/
Class<?>[] modules() default {};
/**
* A list of types that are to be used as <a href="#component-dependencies">component
* dependencies</a>.
*/
Class<?>[] dependencies() default {};
...
}
modules,不必多说,注入提供方;
dependencies直接指定一个class加入注入提供方集合;
(5)@Singleton注解,使用单例模式,若是三方依赖,需配合在提供的@Module同样加上@Singleton;若直接@Singleton本地代码的类,则直接实现单例模式;