Dagger2:基于android的Spring?

来源:互联网 发布:unity3d室内漫游 编辑:程序博客网 时间:2024/06/03 19:46

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写法的一个例子:

@Modulepublic 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.

0 0
原创粉丝点击