我有一个SecurityService类,用于通过Rx2AndroidNetworking获取令牌,我向其建立了一个OkHttpClient,该客户端包含一个拦截器和一个身份验证器,它们也需要调用令牌,这导致我具有周期性依赖性
安全服务:
class SecurityService @Inject constructor(private val preferenceHelper: IPreferenceHelper, private val httpClient: ApiHttpClient): ISecurityService {
override fun getToken(request: TokenRequest): Observable<TokenResponse> =
Rx2AndroidNetworking.post(ApiEndPoint.ENDPOINT_AUTHORIZATION_GET_TOKE)
.addBodyParameter(request)
.setOkHttpClient(httpClient.okHttpClient)
.build()
.getObjectObservable(TokenResponse::class.java)
override fun refreshToken(): Observable<TokenResponse> =
Rx2AndroidNetworking.post(ApiEndPoint.ENDPOINT_AUTHORIZATION_REFRESH_TOKE + preferenceHelper.getRefreshToken())
.setOkHttpClient(httpClient.okHttpClient)
.build()
.getObjectObservable(TokenResponse::class.java)
override fun revokeToken(): Observable<String> =
Rx2AndroidNetworking.post(ApiEndPoint.ENDPOINT_AUTHORIZATION_REVOKE_TOKE + preferenceHelper.getAccessToken())
.setOkHttpClient(httpClient.okHttpClient)
.build()
.getObjectObservable(String::class.java)
}
ApiHttpClient:
class ApiHttpClient @Inject constructor(preferenceHelper: IPreferenceHelper,
securityService: ISecurityService,
compositeDisposable: CompositeDisposable) {
var okHttpClient: OkHttpClient = OkHttpClient().newBuilder()
.addInterceptor(TokenInterceptor(preferenceHelper, securityService, compositeDisposable))
.authenticator(ApiAuthenticator(preferenceHelper, securityService, compositeDisposable))
.build()
}
ApiAuthenticator:
class ApiAuthenticator @Inject constructor(private val preferenceHelper: IPreferenceHelper,
private val securityService: ISecurityService,
private val compositeDisposable: CompositeDisposable) :Authenticator {
override fun authenticate(route: Route, response: Response): Request? {
compositeDisposable.add(securityService.refreshToken().subscribe({ tokenResponse ->
if (tokenResponse != null) {
preferenceHelper.let {
it.setAccessToken(tokenResponse.access_token)
it.setRefreshToken(tokenResponse.refresh_token)
it.setTokenExpiresIn(tokenResponse.expires_in.toString())
it.setUserAuthorities(tokenResponse.authorities.toString())
}
}
}, { err -> Log.w("Authenticate error", err) })) //TODO: Send error message and request login.
return response.request().newBuilder().build()
}
}
TokenInterceptor:
class TokenInterceptor @Inject constructor(private val preferenceHelper: IPreferenceHelper,
private val securityService: ISecurityService,
private val compositeDisposable: CompositeDisposable) :Interceptor {
override fun intercept(chain:Interceptor.Chain):Response {
var token = preferenceHelper.getAccessToken()
if(isTokenExpired(token)){
compositeDisposable.add(securityService.refreshToken().subscribe({ tokenResponse ->
if (tokenResponse != null) {
token = tokenResponse.access_token
preferenceHelper.let {
it.setAccessToken(token)
it.setRefreshToken(tokenResponse.refresh_token)
it.setTokenExpiresIn(tokenResponse.expires_in.toString())
it.setUserAuthorities(tokenResponse.authorities.toString())
}
}
}, { err -> Log.w("Authenticate error", err) })) //TODO: Send error message and request login.
}
return chain.proceed(setAuthHeader(chain.request(), token))
}
}
DI:
AppModule类
@Provides
@Singleton
internal fun provideContext(application: Application): Context = application
@Provides
@Singleton
internal fun providePrefHelper(appPreferenceHelper: AppPreferenceHelper): IPreferenceHelper = appPreferenceHelper
@Provides
@Singleton
internal fun provideSecurityService(securityService: SecurityService): ISecurityService = securityService
@Provides
@Singleton
internal fun provideOkHttpClient(): ApiHttpClient = ApiHttpClient()
@Provides
@PreferenceInfo
internal fun providePrefFileName(): String = AppConstants.PREF_NAME
@Provides
internal fun provideCompositeDisposable(): CompositeDisposable = CompositeDisposable()
@Provides
internal fun provideSchedulerProvider(): SchedulerProvider = SchedulerProvider()
}
错误:
public abstract interface AppComponent {
^
data.network.network.ISecurityService is injected at
data.network.ApiHttpClient.<init>(…, securityService, …)
data.network.ApiHttpClient is injected at
data.network.services.SecurityService.<init>(…, httpClient)
data.network.services.SecurityService is injected at
di.module.AppModule.provideSecurityService$app_debug(securityService)
data.network.network.ISecurityService is injected at
ui.interactor.MainInteractor.<init>(…, securityService)
ui.interactor.MainInteractor is injected at
ui.main.MainActivityModule.provideMainInteractor$app_debug(mainInteractor)
ui.main.interactor.IMainInteractor is injected at
ui.main.presenter.MainPresenter.<init>(interactor, …)
ui.main.presenter.MainPresenter<ui.main.view.IMainView,ui.main.interactor.IMainInteractor> is injected at
ui.main.MainActivityModule.provideMainPresenter$app_debug(mainPresenter)
ui.main.presenter.IMainPresenter<ui.main.view.IMainView,ui.main.interactor.IMainInteractor> is injected at
ui.main.view.MainActivity.presenter
ui.main.view.MainActivity is injected at dagger.android.AndroidInjector.inject(arg0)
ApiHttpClient类取决于ISecurityService和IPreferenceHelper,但在创建SecurityService时需要提供ApiHttpClient。这会导致依赖性循环错误。我该如何打败,有人面对这个问题吗?预先感谢。