Dagger2
Dragger2是Android上的依赖注入框架, 是属于Dragger1的分支项目, 有Google开发维护, 而Dragger1是Square公司受到Google的轻量依赖注入框架Guice的启发创建的依赖注入框架. 后来Google收到Auto项目的启发开发了Dragger2, Auto就没必要介绍了
官网:[GitHub][https://github.com/google/dagger]
依赖注入框架
没有使用依赖注入的时候, 例如在类A中创建类B的对象, 如果类B构造方法发生改变, 类A将无法创建类B对象, 这种产生了很大耦合性. 如果对象创建次数更多后期修改难度将增加. 所以为了解耦出现了依赖注入框架,通过注解来分离类B的创建操作实现业务分离.
实现原理
大部分注解可能都是采用反射原理, 在运行期获取并修改字节码对象. 但是大量使用反射会影响app性能. 因此Dragger2并没有使用反射. 使用的是Java Annotation Processing技术.
Java Annotation Processing: 是Javac用于编译时扫描和解析注解的工具. 在编译时期读取java源码, 解析注解, 生成新的java代码然后再次编译.
Dragger2特点
- 没有使用反射, 所有配置都在编译期完成
- Google宣称相对于Dragger1提升13%性能
- 支持代码混淆
- 简化代码
演示
下面演示分离对象的创建操作
- 创建对象
- module 创建并返回对象
- component 关联对象和类
- inject 注入对象
添加依赖
compile 'com.google.dagger:dagger:2.8'
annotationProcessor 'com.google.dagger:dagger-compiler:2.8'
步骤:
创建需要被分离的类
public class User { private String name; private int age; public User(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } }
创建Module
@Module public class MainActivityModule { @Provides User provideUser() { return new User("姜涛", 21); } }
创建Component, 关联
@Component(modules = MainActivityModule.class) public interface MainActivityComponent { // 此处必须是MainActivity, 不能是Activity void inject(MainActivity activity); }
注入对象之前需要Rebuild以下, 因为dagger2是编译时完成注解解析, 所以需要重编译以下
public class MainActivity extends AppCompatActivity { @Inject User mUser; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 注入对象 DaggerMainActivityComponent.builder() .mainActivityModule(new MainActivityModule()).build() .inject(this); Toast.makeText(this, mUser.getName(), Toast.LENGTH_SHORT).show(); } }
简写注入
dagger2还提供了一种可以省略Module的方式注入对象, 当对象的构造方法发生改变时, 使用该对象的地方会自动改变.
被注入的对象构造方法用@inject注解
public class CustomUser {
@Inject
public CustomUser() {
}
}
Component注解不使用参数
@Component
public interface MainActivityComponent {
void inject(MainActivity activity);
}
开始注入
public class MainActivity extends AppCompatActivity {
@Inject
CustomUser mCustomUser;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerMainActivityComponent build = (DaggerMainActivityComponent) DaggerMainActivityComponent.builder().build();
build.inject(this);
}
}