Dagger2是Dagger1的分支,由谷歌公司接手开发的,Dagger2中没有再使用反射机制,而是使用派遣方法,自动生成如同自己手写的代码,好处是:第一,谷歌声称提高了13%的效率;第二,代码的调试变得更简单,缺点是缺乏灵活性。
在项目的gradle文件中添加
dependencies {
classpath 'com.android.tools.build:gradle:2.2.2'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
}
在app的gradle文件中添加插件
apply plugin: 'com.neenbedankt.android-apt'
apt 'com.google.dagger:dagger-compiler:2.0'
compile 'com.google.dagger:dagger:2.0'
首先了解一下dagger2中的几个注解:
@Inject,该注解有两个作用,标记变量,表示改变量有Dagger2容器提供,不需要自己初始化;标记构造函数,表示该类可以由Dagger2在需要的时候找到该构造方法,并提供该类的实例。
@module,标注用于提供需要注入的实例的类,当我们要提供第三方的依赖时,使用Inject注解类的构造函数很明显不现实,这时就可以使用这个注解,在module中提供。
事件出真知,我们以汽车和引擎为例
引擎类,依赖提供
public class Engine {
@Inject
public Engine() {
}
public void start(){
System.out.print("引擎发动了");
}
}
public class Bus {
@Inject
Engine engine;
public Bus(){
DaggerBusComponent.builder().build().inject(this);
}
}
@Component
public interface BusComponent {
void inject(Bus bus);
}
public class TestMain {
public static void main(String args[]) {
new Bus().engine.start();
}
}
运行之后,如愿打印出信息,那我们就来分析一下,这个简单的例子是怎么实现依赖注入的呢?
这里一共涉及到三个类,DaggerBusComponent,Bus_MembersInjector,Engine_Factory
public final class DaggerBusComponent implements BusComponent {
private MembersInjector busMembersInjector;
private DaggerBusComponent(Builder builder) {
assert builder != null;
initialize(builder);
}
public static Builder builder() {
return new Builder();
}
public static BusComponent create() {
return builder().build();
}
@SuppressWarnings("unchecked")
private void initialize(final Builder builder) {
this.busMembersInjector = Bus_MembersInjector.create(Engine_Factory.create());
}
@Override
public void inject(Bus bus) {
busMembersInjector.injectMembers(bus);
}
public static final class Builder {
private Builder() {
}
public BusComponent build() {
return new DaggerBusComponent(this);
}
}
}
Bus_MembersInjector,注入类
public final class Bus_MembersInjector implements MembersInjector {
private final Provider engineProvider;
public Bus_MembersInjector(Provider engineProvider) {
assert engineProvider != null;
this.engineProvider = engineProvider;
}
public static MembersInjector create(Provider engineProvider) {
return new Bus_MembersInjector(engineProvider);
}
@Override
public void injectMembers(Bus instance) {
if (instance == null) {
throw new NullPointerException("Cannot inject members into a null reference");
}
instance.engine = engineProvider.get();
}
public static void injectEngine(Bus instance, Provider engineProvider) {
instance.engine = engineProvider.get();
}
}
Engine_Factory,看名字也能看出来是专门负责产生对象的工厂类
public final class Engine_Factory implements Factory {
private static final Engine_Factory INSTANCE = new Engine_Factory();
@Override
public Engine get() {
return new Engine();
}
public static Factory create() {
return INSTANCE;
}
}
首先看Dagger2给我们生成的DaggerBusComponent类
我们一步一步往下看
第一步,在我们构造DaggerBusComponent对象是会调用initialize(builder)方法,该方法会创建两个对象Bus_MembersInjector,Engine_Factory;
在Engine_Factory.create()中,会直接返回Engine_Factory单例对象,在Bus_MembersInjector.create()方法,把刚创建的Engine_Factory对象作为成员变量,并初始化DaggerBusComponent中的busMembersInjector成员变量,看到这里还是只知道其中类的关系,还是不知道到底怎么依赖,怎么注入的,别着急,慢慢往下看;
第二步,在调用Bus类中调用DaggerBusComponent的inject(Bus bus),真正调用的是Bus_MembersInjector的inject(),接下来就是关键代码instance.engine = engineProvider.get();这里,直接把engine对象赋值给bus对象的engine变量,这个engine对象来源于Engine_Factory类,而且这个对象是直接由Engine_Factory直接new出来的,至此,该案例分析完毕,哈哈,仰天大笑出门去,我辈岂是蓬蒿人。
案例2
我们还是以汽车和引擎为例,只不过这次我们的引擎的构造函数需要传入齿轮gear,并且齿轮的构造函数需要传入型号参数
一共有6各类
齿轮类Gear
public class Gear {
private String code;
public Gear(String code) {
this.code=code;
}
public void sayCode(){
System.out.print("齿轮的型号是:"+code);
}
}
public class Engine {
Gear gear;
public Engine(Gear gear) {
this.gear=gear;
}
public void start(){
gear.sayCode();
}
}
public class Bus {
@Inject
Engine engine;
public Bus(){
DaggerBusComponent.builder().busModule(new BusModule()).build().inject(this);
}
}
BusModule,用来提供依赖
@Module
public class BusModule {
@Provides
Engine provideEngine(Gear gear){
return new Engine(gear);
}
@Provides
Gear provideGear(){
return new Gear("G型号齿轮");
}
}
@Component(modules ={BusModule.class} )
public interface BusComponent {
void inject(Bus bus);
}
public class TestMain {
public static void main(String args[]) {
new Bus().engine.start();
}
}
齿轮的型号是:G型号齿轮
首先调用的是DaggerBusComponent中的initialize()方法
@SuppressWarnings("unchecked")
private void initialize(final Builder builder) {
this.provideGearProvider = BusModule_ProvideGearFactory.create(builder.busModule);
this.provideEngineProvider =
BusModule_ProvideEngineFactory.create(builder.busModule, provideGearProvider);
this.busMembersInjector = Bus_MembersInjector.create(provideEngineProvider);
}
在改方法中会产生三个分别类型为Provider
接下来调用的是DaggerBusComponent的inject()方法,其实调用的是Bus_MembersInjector的injectMembers()方法
@Override
public void injectMembers(Bus instance) {
if (instance == null) {
throw new NullPointerException("Cannot inject members into a null reference");
}
instance.engine = engineProvider.get();
}
@Override
public Engine get() {
return Preconditions.checkNotNull(
module.provideEngine(gearProvider.get()),
"Cannot return null from a non-@Nullable @Provides method");
}
@Provides
Engine provideEngine(Gear gear){
return new Engine(gear);
}
同时关键的地方来了,我们关心的是这个参数gear就是由gearProvider.get()方法提供,这个方法调用BusModule_ProvideGearFactory类中的get()方法,
@Override
public Gear get() {
return Preconditions.checkNotNull(
module.provideGear(), "Cannot return null from a non-@Nullable @Provides method");
}