您的位置:首页 > 编程语言 > Java开发

Dagger2:基于android的Spring?

2016-09-26 11:27 267 查看

Dagger2 基于android的Spring

前几天刚好项目不忙, 去看看Dagger2的学习资料,为什么到现在才看它呢?

也许是它不容易上手一个原因吧, 但更多的是我个人的执念,我就觉得基于注解和反射的东西都不是什么好东西?

呵呵 , 但最近看到它是越来越多的被集成于的项目中去,并且经常和rxjava绑在一起使用,感觉也是非常的牛逼。大家都说好,那我也虚心学习下咯。断断续续学了几天,总结一下。

Dagger2的定义:使用DI来实现IOC的容器。

本节内容:

@Inject

@Component

@Module

@Inject是如何寻找对象的?

用过Butterknife的人都知道 ,使用@Bind(R.id.name) 这样的注解可以让框架自动的从本页面寻找id对应的View. 在这里,使用@Inject来寻找该类对应的实例.这里有一个疑问,在传统的编程当中,对应一个是有new作为关键字来创建的,或通过其他克隆、反射、字节码注册等等方式来创建。那dagger2是如何去寻找对象实例的呢?

有两种方式,一种是通过@Inject-@Inject方式,连接类的构造函数和被依赖对象实例的对接。另外一种,就是通过其他注解进行绑定和容器注册提供对象。同时还可以指定改类为单例。后面再讲给大家。

先了解一下通过@inject绑定构造函数方式:

class A{
@Inject
B b;

}
class B{

@Inject
public B(){

}
}


假设有A类中的引用了B对象的实例b,并且使用了@Inject注解,它告诉B说我要用到你的实例了,那么B就回去找对象给它, 找哪个对象呢?

在B里,也要有一个被@Inject标识的构造函数。就表明,哦 我要用这个构造函数new一个对象给A。这时候关系就明了。不使用new也可以创建出对象了。如果在构造函数上加@SingleTon的话,还表明,所有引用的实例是全局单一的,这里读者可以debug看看它们的内存地址就可以知道。

第二种寻找对象的方式等介绍完注解后再连贯起来就好明白了。

@Component 是controller?

这里指component类似于controller为什么?因为作者理解Inject-Component-Module的关系就类似于View-Controller-Model. 的基于三角关系的三基友.


可以笼统的理解为:Inject或者View是资源的消费者,专门使用. 而Controller和Component则是连接消费和生产者的中间件.对消费者和生产者进行关联和处理关系等等.而Module和Model则是资源的生产者了.这样理解那Dagger2的使用原理的就清晰多了.

那么在@Component注解怎么使用?贴一个ActivityComponent的代码出来描述下:

@Component( modules = ActivityModule.class)
public interface ActivityComponent {

void inject(MainActivity mainActivity);

}


在ActivityComponent类中,@Component的里指定了modules为ActivityModule.class,还可以多指定,指定想多个Module.实现Componnent共用是可以的,而接口方法里,提供了个inject(MainActivity mainActivity);方法来帮顶消费者.也就是说,在MainActivity里

ActivityComponent mActivityComponent = DaggerActivityComponent.builder()
.applicationComponent(((App) getApplication()).getApplicationComponent())
.activityModule(new ActivityModule(this))
.build();
mActivityComponent.inject(this);//调用上面的方法绑定MainActivity


这样使用.这个架构的连接就构成了,绑定好了。

资源的生产者~Module

通过上面那样理解,那么这里就很好理解了。详细说下,Module里涉及到其他几个注解。

看下module写法的一个例子:

@Module
public class ActivityModule {
private Activity mActivity;

public ActivityModule(Activity activity) {
mActivity = activity;
}

@Provides
public Context ProvideActivityContext() {
return mActivity;
}

@Provides
public Activity ProvideActivity() {
return mActivity;
}
}


类头有个@Module是固定的, 和@Component一样的.这个还涉及到了一个@provides注解.在module里的方法,需要想容器里注入的方法都要加上该注解.这个是必须的.

前面说的神秘的第二种方式是啥?

其实@inject-@inject方法通常都是自己的内部代码的一种实现方法,在使用到一些第三方库的时候,我们很少去该他开源的代码,有时候也改不了人家的代码.那么这时候我们就要使用”第二计划”来桥接这种依赖注入的关系了.其实真相就是上面的@Provides注解就是用来解决这类问题的.Module中的创建类实例方法用Provides进行标注,Component在搜索到目标类中用Inject注解标注的属性后,Component就会去Module中去查找用Provides标注的对应的创建类实例方法,这样就可以解决第三方类库用dagger2实现依赖注入了。也就是说在 module中返回对应目标类的对象,容器就会自动的将其注入.在使用的地方取出就可以了.

其实第一种方式和第二种方式只是存的方式有些不同,取还是一样的.同时,在@Inject使用时,容器他会优先使用第二种方式来取,加入取不到,它才会用第一种发那个是来取.

总结

本人也是刚接触dagger2,没有理解的太深刻不敢胡乱妄加断言,以免混淆后来者的学习和理解.只是做了蜻蜓点水.做一下使用介绍.如有错误,还忘海涵和指出,虚心受教了.谢谢您的阅读,祝您早日找到女盆友,脱离这个单身男性交友论坛.thks.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android spring