You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dagger2报错:@Component.Builder缺少RestModule的必需Setter

解决Dagger @Component.Builder缺少RestModule Setter的错误

这个错误的核心原因很明确:你的RestModule拥有一个带RestSettings参数的构造函数,而Dagger的@Component.Builder需要明确的方式来获取这个模块的实例——因为Dagger无法自动创建它(它不知道从哪里拿到RestSettings)。下面是两种常见的解决方案:

方案一:在Component Builder中添加RestModule的Setter方法

这是最直接的方式,手动把实例化好的RestModule传递给Dagger:

修改PresenterEnvironmentComponent的Builder

在Builder接口中添加一个专门设置RestModule的方法:

@Singleton
@Component(modules = {PresenterEnvironmentModule.class, RestModule.class})
public interface PresenterEnvironmentComponent {
    @Component.Builder
    interface Builder {
        // 保留你现有的@BindsInstance方法
        @BindsInstance Builder sharedPreferenceService(SharedPrefService sharedPreferences);
        @BindsInstance Builder loggingService(LoggingService loggingService);
        @BindsInstance Builder applicationService(Application application);
        @BindsInstance Builder connectivityService(ConnectivityService connectivityService);
        @BindsInstance Builder schedulersService(SchedulersService schedulersService);
        @BindsInstance Builder sessionService(SessionService sessionService);
        
        // 添加这一行:提供RestModule的setter
        Builder restModule(RestModule restModule);

        PresenterEnvironmentComponent build();
    }

    // 保留其他方法
    @NonNull PresenterEnvironment presenterEnvironment();
    void inject(BaseBootstrapActivity<BaseBootstrapPresenter> baseBootstrapActivity);
}

使用时传入RestModule实例

在创建Component的地方,先实例化RestModule,再通过Builder传入:

// 先准备好RestSettings实例
RestSettings restSettings = new RestSettings(...);
// 实例化RestModule
RestModule restModule = new RestModule(restSettings);

// 创建Component
PresenterEnvironmentComponent component = DaggerPresenterEnvironmentComponent.builder()
    .sharedPreferenceService(yourSharedPrefService)
    .loggingService(yourLoggingService)
    // 其他必要的@BindsInstance参数
    .restModule(restModule) // 传入RestModule
    .build();

方案二:让Dagger管理RestModule的依赖(更优雅的方式)

如果你不想手动实例化RestModule,可以把RestSettings改成由Dagger注入的依赖,然后修改RestModule去掉带参构造:

修改RestModule

移除构造函数和成员变量,在需要用到RestSettings的@Provides方法中直接注入它:

@Module
public class RestModule {
    // 去掉原来的构造函数和成员变量

    @Provides
    @Singleton
    @NonNull
    @Type.Basic
    public OkHttpClient provideOkHttpClient(
            @NonNull RestSettings restSettings,
            @NonNull TokenInterceptor tokenInterceptor,
            @NonNull HttpLoggingInterceptor loggingInterceptor,
            @NonNull OkLogInterceptor okLogInterceptor,
            @NonNull CachingInterceptor cacheInterceptor
    ) {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.addInterceptor(tokenInterceptor);

        // 用restSettings获取原来的成员变量值
        Interceptor[] additionalInterceptors = restSettings.getAdditionalInterceptors();
        if (additionalInterceptors != null && additionalInterceptors.length > 0) {
            for (Interceptor interceptor : additionalInterceptors) {
                builder.addInterceptor(interceptor);
            }
        }

        Function<OkHttpClient.Builder, OkHttpClient.Builder> onOkHttpClient = restSettings.getOnOkHttpClient();
        if (onOkHttpClient != null) {
            builder = apply(onOkHttpClient, builder);
        }

        if (restSettings.isDebuggable()) {
            builder.addInterceptor(loggingInterceptor);
            builder.addNetworkInterceptor(cacheInterceptor);
            builder.addInterceptor(okLogInterceptor);
        }

        return builder.build();
    }

    // 其他@Provides方法同理,把原来的成员变量替换为restSettings的调用
    @Provides
    @Singleton
    @NonNull
    @Type.ForUploading
    public OkHttpClient provideOkHttpClientForUploading(
            @NonNull RestSettings restSettings,
            @NonNull TokenInterceptor tokenInterceptor,
            @NonNull HttpLoggingInterceptor loggingInterceptor,
            @NonNull OkLogInterceptor okLogInterceptor,
            @NonNull CachingInterceptor cacheInterceptor
    ) {
        // 同样的逻辑,用restSettings获取参数
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.addInterceptor(tokenInterceptor);

        Interceptor[] additionalInterceptors = restSettings.getAdditionalInterceptors();
        if (additionalInterceptors != null && additionalInterceptors.length > 0) {
            for (Interceptor interceptor : additionalInterceptors) {
                builder.addInterceptor(interceptor);
            }
        }

        Function<OkHttpClient.Builder, OkHttpClient.Builder> onOkHttpClientForUploading = restSettings.getOnOkHttpClientForUploading();
        if (onOkHttpClientForUploading == null) {
            builder.writeTimeout(60, TimeUnit.SECONDS);
            builder.connectTimeout(60, TimeUnit.SECONDS);
            builder.readTimeout(60, TimeUnit.SECONDS);
        } else {
            builder = apply(onOkHttpClientForUploading, builder);
        }

        if (restSettings.isDebuggable()) {
            builder.addInterceptor(loggingInterceptor);
            builder.addNetworkInterceptor(cacheInterceptor);
            builder.addInterceptor(okLogInterceptor);
        }

        return builder.build();
    }

    // 保留其他无依赖的@Provides方法
    @Provides
    @Singleton
    @NonNull
    public OkLogInterceptor provideOkLogInterceptor() {
        return new OkLogInterceptor.Builder().withAllLogData().build();
    }

    @Provides
    @Singleton
    @NonNull
    public HttpLoggingInterceptor provideHttpLoggingInterceptor() {
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        return interceptor;
    }

    @Provides
    @Singleton
    @NonNull
    @Type.Basic
    public Retrofit provideRetrofit(@NonNull @Type.Basic OkHttpClient client, @NonNull RestSettings restSettings) {
        return new Retrofit.Builder()
                .baseUrl(restSettings.getBaseUrl())
                .client(client)
                .addConverterFactory(LoganSquareConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
    }

    // 补全provideRetrofitForUploading方法,同样注入RestSettings
}

在Component Builder中添加RestSettings的@BindsInstance方法

把RestSettings也加入到Builder的绑定中:

@Singleton
@Component(modules = {PresenterEnvironmentModule.class, RestModule.class})
public interface PresenterEnvironmentComponent {
    @Component.Builder
    interface Builder {
        // 保留原有@BindsInstance方法
        @BindsInstance Builder sharedPreferenceService(SharedPrefService sharedPreferences);
        @BindsInstance Builder loggingService(LoggingService loggingService);
        @BindsInstance Builder applicationService(Application application);
        @BindsInstance Builder connectivityService(ConnectivityService connectivityService);
        @BindsInstance Builder schedulersService(SchedulersService schedulersService);
        @BindsInstance Builder sessionService(SessionService sessionService);
        
        // 添加RestSettings的绑定
        @BindsInstance Builder restSettings(RestSettings restSettings);

        PresenterEnvironmentComponent build();
    }

    // 保留其他方法
    @NonNull PresenterEnvironment presenterEnvironment();
    void inject(BaseBootstrapActivity<BaseBootstrapPresenter> baseBootstrapActivity);
}

使用时传入RestSettings

现在创建Component只需要传入RestSettings,Dagger会自动创建RestModule并注入所需的依赖:

RestSettings restSettings = new RestSettings(...);

PresenterEnvironmentComponent component = DaggerPresenterEnvironmentComponent.builder()
    .sharedPreferenceService(yourSharedPrefService)
    .loggingService(yourLoggingService)
    // 其他必要参数
    .restSettings(restSettings)
    .build();

两种方案都能解决你的问题,方案二更符合Dagger的依赖注入理念,减少手动实例化模块的代码;方案一更适合快速修复现有代码结构。

内容的提问来源于stack exchange,提问作者Hanaa Mohamed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:04:20