Dagger2 @Provides与@Binds的区别和联系

本文主要探讨了@Provides和@Binds的区别与联系。@Provides可无参或含参,参数来源多样;@Binds语法与@Provides差异大。二者都用于提供依赖,但创建方式有别,@Provides由开发者直接参与,@Binds通过注解标注构造方法由框架帮忙,最终使用时都引用目标实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Dagger2 创建的区别和联系

前言

关于@Provides@Binds的用法,经常叫不准,特地记录找到区别和联系

@Provides

无参

    @Singleton
    @Provides
    static List<FragmentManager.FragmentLifecycleCallbacks> provideFragmentLifecycles() {
        return new ArrayList<>();
    }

含参

    @Singleton
    @Provides
    static Cache<String, Object> provideExtras(Cache.Factory cacheFactory) {
        //noinspection unchecked
        return cacheFactory.build(CacheType.EXTRAS);
    }

参数来源:

  1. @Component内通过modules关联的其他@Module提供
@Singleton
@Component(modules = {AppModule.class, ClientModule.class, GlobalConfigModule.class})
public interface AppComponent { ...

如上AppModule.class内部Cache<String, Object> provideExtras需要GlobalConfigModule.class提供的数据(Cache.Factory),因为是通过modules相关联,所以可以直接调用到。

至于GlobalConfigModule.class的数据(Cache.Factory)也可以是由GlobalConfigModule.class自己通过 @Provides提供,也可以是通过@Component.Builder注入。

  1. @Module内部的@Provides方法提供
  2. @Component内通过dependencies关联的其他@Module提供

假设说,我们的LoginModule.class也需要Cache.Factory这个数据,此时Cache.FactoryAppComponent.class提供

@ActivityScope
@Component(modules = LoginModule.class, dependencies = AppComponent.class)
public interface LoginComponent {

因为是用dependencies 相关联,所以如果要用到Cache.Factory就需要AppComponent.class内部将Cache.Factory声明(将Cache.Factory开放给其他Component使用)出来,如下:

@Singleton
@Component(modules = {AppModule.class, ClientModule.class, GlobalConfigModule.class})
public interface AppComponent {

	//....略

    /**
     * 用于创建框架所需缓存对象的工厂
     *
     * @return {@link Cache.Factory}
     */
    Cache.Factory cacheFactory();

@Binds

@Binds的语法和@Provides的差距真是太大了,所以根本不能当成一样的看。

先看一段代码:

    @Binds
    @Named("ActivityLifecycle")
    abstract Application.ActivityLifecycleCallbacks bindActivityLifecycle(ActivityLifecycle activityLifecycle);

    @Binds
    @Named("ActivityLifecycleForRxLifecycle")
    abstract Application.ActivityLifecycleCallbacks bindActivityLifecycleForRxLifecycle(ActivityLifecycleForRxLifecycle 
    																						activityLifecycleForRxLifecycle);

了解一下:

  1. @Named😒 用于区分两个实例,如果返回值只有一个Application.ActivityLifecycleCallbacks 那么肯定是不需要 @Named

  2. Application.ActivityLifecycleCallbacks :它是返回值,同时也是两个参数的父类,ActivityLifecycle ActivityLifecycleForRxLifecycle都继承于它。

  3. 使用

    @Inject
    @Named("ActivityLifecycle")
    protected Application.ActivityLifecycleCallbacks mActivityLifecycle;
    @Inject
    @Named("ActivityLifecycleForRxLifecycle")
    protected Application.ActivityLifecycleCallbacks mActivityLifecycleForRxLifecycle;

@Provides并无差别。

  1. @Provides是通过自己通过new或者build(大部分build内部也是new实现)等创建类,那么@Binds是怎么创建我们需要的对象呢?

通过参数ActivityLifecycle ActivityLifecycleForRxLifecycle点入,我们发现内部其实就是完整的功能实现

发现他的构造函数:

@Singleton
public class ActivityLifecycle implements Application.ActivityLifecycleCallbacks {

	//...略
	
    @Inject
    public ActivityLifecycle() {
    }

这里就有必要了解一下 JSR330JSR330Jcp 给出的官方标准反向依赖注入规范。Java大部分反向依赖注入的工具或者框架目前基本上都满足 JSR330 规范、例如 springguice 以及Dagger

JSR@Inject可以当做@AutoWired 来使用。其是用来定义自动注入的,而且与@AutoWired 一样,@Inject可以标注在fieldmethodconstructor上。

即: @Inject可以用于变量、方法、构造方法上!
用于构造方法上的 @Inject会帮助当前类,通过调用注解标注的构造方法来创建实例。

在这里插入图片描述
绿色框的位置就是 @Inject帮忙实现的部分。自己看吧!

总结

  1. @Provides@Binds都是提供依赖(可以理解成类的实例,接口实例)
  2. @Provides@Binds对于创建有所区别。@Provides是由开发者直接通过new的方式参与其中;@Binds是由开发者用@Inject注解标注目标类的构造方法,由dagger帮忙new
  3. 无论是@Provides还是@Binds,最后在使用的时候都是通过@Inject引用,引用到的都是目标实例,创建好的那种。

参考地址

https://yq.aliyun.com/articles/626235?utm_content=m_1000013558

有问题随时欢迎沟通,相互学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周周都刷火焰猫头鹰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值