dagger2 依赖注入
前言:
当 mvp + dagger2 + rxjava 三者遇上,架构更加清晰,代码更加灵活,巧妙结合。
依赖注入:是为了解耦,达到高内聚低耦合的目的,保证代码的健壮性、灵活性和可维护性。
1 public class Computer{ 2 3 private Cpu cpu; 4 5 public Computer(){ 6 cpu= new Cpu(); 7 } 8 }
Computer类持有了对Cpu实例的引用,称之为Computer类对Cpu类有一个依赖。
依赖注入则是指通过注入的方式实现类与类之间的依赖。
1、构造注入:通过构造函数传参,给依赖的成员变量赋值,因此实现注入。
1 public class Computer{ 2 3 private Cpu cpu; 4 5 public Computer(Cpu cpu){ 6 this.cpu= cpu; 7 } 8 }
2、接口注入:实现事先定义好的接口方法,通过方法传参的方式实现注入。
public interface Injection<T>{ void inject(T t); } public class Computer implements Injection<Cpu>{ private Cpu cpu; public Computer(){ } public void inject(Cpu cpu){ this.cpu= cpu; } }
3、注解注入:使用Java注解,在编译阶段生成代码实现注入或者是在运行阶段通过反射实现注入。
public class Computer{ @Inject private Cpu cpu; public Computer(){ } }
Dagger2是通过Java注解在编译期来实现依赖注入的。
Dagger2的常用注解:
@Inject:
1、用来标记需要依赖的变量,须为它提供依赖;
2、是用来标记构造函数,Dagger2通过@Inject注解可以在需要这个类实例的时候来找到这个构造函数并把相关实例构造出来,以此来为被@Inject标记了的变量提供依赖;
@Module:
用于标注提供依赖的类。当构造函数带有参数,或者是第三方库类时,所须使用的。
@Provides:
用于标注Module所标注的类中的方法,该方法在需要提供依赖时被调用,把预先提供好的对象当做依赖给标注了@Inject的变量赋值;
@Component:
用于标注接口,是依赖需求方和依赖提供方之间的桥梁。被Component标注的接口在编译时会生成该接口的实现类(如果@Component标注的接口为CarComponent,则编译期生成的实现类为DaggerCarComponent),我们通过调用这个实现类的方法完成注入;
@Scope:
用于自定义注解,我能可以通过@Scope自定义的注解来限定注解作用域,实现局部的单例;
@Singleton:
其实就是一个通过@Scope定义的注解,我们一般通过它来实现全局单例。但实际上它并不能提前全局单例,是否能提供全局单例还要取决于对应的Component是否为一个全局对象。
案例一:
没有使用注入时:
public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); User user = new User(); ((TextView) findViewById(R.id.tv_username)).setText("user name:" + user.name); } ... }
使用注入时:
设置 build.gradle
, 并添加依赖库.
android-apt
, 提供 dagger2使用编译生成类 的功能.
1 buildscript { 2 repositories { 3 jcenter() 4 } 5 dependencies { 6 classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' 7 } 8 } 9 10 apply plugin: 'com.neenbedankt.android-apt' // 注释处理
dagger2
, 提供 dagger2支持 的功能.
1 compile 'com.google.dagger:dagger:2.0.2' // dagger2 2 compile 'com.google.dagger:dagger-compiler:2.0.2' // dagger2
annotation
, 提供 java注释解析 的功能.
1 provided 'javax.annotation:jsr250-api:1.0' // Java标注
配置完成后:
首先定义Module类来生成依赖对象。使用@Provides是用来标注具体提供依赖对象的方法。
1 @Module 2 public class DataModule { 3 4 @Provides 5 UserModel provideUser() { 6 return new User(); 7 } 8 }
定义component:注入器,加上modules = {DataModule.class},是用来告诉Dagger2提供依赖的是DataModule这个类:
1 @Component(modules = DataModule.class) 2 public interface ActivityComponent { 3 void inject(MainActivity activity); 4 }
最后使用方式:构建时,使用dataModule(new DataModule()),注入器DaggerActivityComponent把DataModule提供的依赖 注入到 MainActivity中,注入,使用
1 public class MainActivity extends ActionBarActivity { 2 3 private ActivityComponent mActivityComponent; 4 5 @Inject 6 User user; 7 8 @Override 9 protected void onCreate(Bundle savedInstanceState) { 10 super.onCreate(savedInstanceState); 11 setContentView(R.layout.activity_main); 12 13 // 构建 14 mActivityComponent = DaggerActivityComponent.builder().dataModule(new DataModule()).build(); 15 16 // 注入 17 mActivityComponent.inject(this); 18 19 ((TextView) findViewById(R.id.tv_username)).setText("user name:" + user.username); 20 } 21 ... 22 }
附言:
当复仇者联盟遇上Dagger2、RxJava和Retrofit的巧妙结合