依赖注入
控制反转(IoC)与依赖注入(DI)
浅谈依赖注入
理解依赖注入(IOC)和学习Unity
Gradle配置(gradle插件2.3以上)
dependencies {
compile 'com.google.dagger:dagger:2.11'
annotationProcessor 'com.google.dagger:dagger-compiler:2.11'
}
@Inject
注解构造函数:通过标记构造函数,告诉Dagger 2可以创建该类的实例(Dagger2通过Inject标记可以在需要这个类实例的时候来找到这个构造函数并把相关实例new出来)从而提供依赖关系。
注解依赖变量:通过标记依赖变量,Dagger2提供依赖关系,注入变量
注解构造函数
public class Test{
@inject
public Test(){
}
}
注解依赖变量
public class Test1{
@inject
Test test;
}
若注解了依赖变量,而没注解构造函数,将获得一个null对象。
若注解了构造函数,没有 注解依赖变量,将不创建实例。
@Provides
@Provides依然是为了提供依赖关系,是对@Inject的补充,弥补了@inject对于第三方框架和接口类的盲区。
@Provides方法本身可能也拥有自身的依赖关系
@Provides方法本身是不能独立存在的,它必须依附于一个Module。
@Module
通过注解类,为Dagger提供依赖关系
@Module
public class TestModule {
@Provides
public Test provideTest() {
return new Test();
}
}
@Component
通过注解接口类,作为提供依赖和所需依赖之间的桥梁,在编译时生成相关实例,将相关依赖注入完成使命。
@Component(modules={Test.class,Test1.class})
public interface TestComponent{
void inject(Class class);
}
依赖规则
若@Injdec和@Module都提供了依赖对象
1.查找Module中是否存在创建该类的方法
2.若存在,初始化参数,完成实例创建
3.不存在用@Inject创建实例
依赖迷失
@Qualifier
限定标识符
1.自定义@Qualifier
@Qualifier // 限定符
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Test{
String value() default "";
}
2.Module中使用
@Module()
public class TestTModule {
@Test("test1")
@Provides
public Test provideTest1() {
return new test1();
}
@Test("test2")
@Provides
public Test provideTest2() {
return new test2();
}
}
3.注入test实例
pubic class Test{
@Test("test1")
@Inject
Test test1;
@Test("test2")
@Inject
Test test2;
}
@Scope
来标识范围的注解,并控制如何重复使用类的实例。仅用@inject注解,未用@Scope注解,在每次依赖注入的时候都会创建新的实例。使用@Scope注解会缓存第一次创建的实例,然后重复注入缓存的实例,不会创建新的实例。
如果有类注入实例的类被@Scope注解,那么其Component必须被相同的Scope注解。
如果依赖实例的注入来源是@Provides方法时,@Provides方法必须被@Scope注解;如果依赖实例的注入来源是@Inject注解的构造函数时,实例类必须被@Scope注解。
@Scope实际上是对注入器的控制。
@Singleton
@Singleton是@Scope的一个特例,或者是说是@Scope的一种实现方式。
@Singleton注解一个类表明该类的创建采用的是单例模式,其会被多个线程共同使用
Lazy<T>
对于任何绑定的对象T,当你想惰性实例化它时,都可以创建一个延迟实例化的Lazy<T>。当你需要它时,调用get()方法时,就会实例化对象。
public class Test {
@Inject
public Test() {
}
}
public class TestActivity extends AppCompatActivity {
@Inject
Lazy<Test> mTest;
@Override
protected void onCreate(Bundle savedInstanceState) {
Test test1= mTest.get();
Log.d("test", test1.toString());
Test test2= mTest.get();
Log.d("test", test2.toString());
}
}
Provider<T>
用法同Lazy<T>
当Provider<T> 每次调用get()方法时,都会执行绑定逻辑并创建一个实例。