From db57b0c29e83a2efec895875b9e1c74f50635a63 Mon Sep 17 00:00:00 2001 From: Ahoo Wang Date: Thu, 18 Jan 2024 13:57:23 +0800 Subject: [PATCH] feat: Split `LoadBalancedWebClientFactoryBean` (#4) --- .idea/compiler.xml | 4 +- gradle.properties | 2 +- .../spring/AbstractWebClientFactoryBean.kt | 47 ++++++++++++++++ .../me/ahoo/coapi/spring/CoApiRegistrar.kt | 7 ++- .../LoadBalancedWebClientFactoryBean.kt | 38 +++++++++++++ .../ahoo/coapi/spring/WebClientFactoryBean.kt | 56 +------------------ 6 files changed, 96 insertions(+), 58 deletions(-) create mode 100644 spring/src/main/kotlin/me/ahoo/coapi/spring/AbstractWebClientFactoryBean.kt create mode 100644 spring/src/main/kotlin/me/ahoo/coapi/spring/LoadBalancedWebClientFactoryBean.kt diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 775ca9a..a32e52c 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -2,8 +2,8 @@ - - + + \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 27c38a9..71e920c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,7 +18,7 @@ kotlin.code.style=official ksp.incremental=true ksp.incremental.log=true group=me.ahoo.coapi -version=0.2.0 +version=0.2.2 description=Streamlining HTTP client definition in Spring 6, CoApi provides zero boilerplate code auto-configuration for more convenient and efficient interface calls. website=https://github.com/Ahoo-Wang/CoApi issues=https://github.com/Ahoo-Wang/CoApi/issues diff --git a/spring/src/main/kotlin/me/ahoo/coapi/spring/AbstractWebClientFactoryBean.kt b/spring/src/main/kotlin/me/ahoo/coapi/spring/AbstractWebClientFactoryBean.kt new file mode 100644 index 0000000..fbe2596 --- /dev/null +++ b/spring/src/main/kotlin/me/ahoo/coapi/spring/AbstractWebClientFactoryBean.kt @@ -0,0 +1,47 @@ +package me.ahoo.coapi.spring + +import org.springframework.beans.factory.FactoryBean +import org.springframework.context.ApplicationContext +import org.springframework.context.ApplicationContextAware +import org.springframework.web.reactive.function.client.ExchangeFilterFunction +import org.springframework.web.reactive.function.client.WebClient + +abstract class AbstractWebClientFactoryBean(private val definition: CoApiDefinition) : + FactoryBean, + ApplicationContextAware { + protected lateinit var appContext: ApplicationContext + + protected open val filterCustomizer: (MutableList) -> Unit = {} + + override fun getObjectType(): Class<*> { + return WebClient::class.java + } + + override fun getObject(): WebClient { + val clientBuilder = appContext.getBean(WebClient.Builder::class.java) + clientBuilder.baseUrl(definition.baseUrl) + val filters = getFilters() + filters.distinct().forEach { + clientBuilder.filter(it) + } + return clientBuilder.build() + } + + protected fun getFilters(): List { + return buildList { + definition.filters.forEach { filterName -> + val filter = appContext.getBean(filterName, ExchangeFilterFunction::class.java) + add(filter) + } + definition.filterTypes.forEach { filterType -> + val filter = appContext.getBean(filterType) + add(filter) + } + filterCustomizer(this) + } + } + + override fun setApplicationContext(applicationContext: ApplicationContext) { + this.appContext = applicationContext + } +} diff --git a/spring/src/main/kotlin/me/ahoo/coapi/spring/CoApiRegistrar.kt b/spring/src/main/kotlin/me/ahoo/coapi/spring/CoApiRegistrar.kt index 2ccf67e..80c25b3 100644 --- a/spring/src/main/kotlin/me/ahoo/coapi/spring/CoApiRegistrar.kt +++ b/spring/src/main/kotlin/me/ahoo/coapi/spring/CoApiRegistrar.kt @@ -46,7 +46,12 @@ class CoApiRegistrar(private val registry: BeanDefinitionRegistry) { } return } - val beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(WebClientFactoryBean::class.java) + val webClientFactoryBeanClass = if (coApiDefinition.loadBalanced) { + LoadBalancedWebClientFactoryBean::class.java + } else { + WebClientFactoryBean::class.java + } + val beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(webClientFactoryBeanClass) beanDefinitionBuilder.addConstructorArgValue(coApiDefinition) registry.registerBeanDefinition(coApiDefinition.webClientBeanName, beanDefinitionBuilder.beanDefinition) } diff --git a/spring/src/main/kotlin/me/ahoo/coapi/spring/LoadBalancedWebClientFactoryBean.kt b/spring/src/main/kotlin/me/ahoo/coapi/spring/LoadBalancedWebClientFactoryBean.kt new file mode 100644 index 0000000..070ce6e --- /dev/null +++ b/spring/src/main/kotlin/me/ahoo/coapi/spring/LoadBalancedWebClientFactoryBean.kt @@ -0,0 +1,38 @@ +/* + * Copyright [2022-present] [ahoo wang (https://github.com/Ahoo-Wang)]. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package me.ahoo.coapi.spring + +import org.springframework.cloud.client.loadbalancer.reactive.LoadBalancedExchangeFilterFunction +import org.springframework.web.reactive.function.client.ExchangeFilterFunction + +/** + * @see org.springframework.cloud.client.loadbalancer.reactive.LoadBalancedExchangeFilterFunction + */ +class LoadBalancedWebClientFactoryBean(definition: CoApiDefinition) : + AbstractWebClientFactoryBean(definition) { + companion object { + private val loadBalancedFilterClass = LoadBalancedExchangeFilterFunction::class.java + } + + override val filterCustomizer: (MutableList) -> Unit + get() = { filters -> + val hasLoadBalancedFilter = filters.any { filter -> + filter is LoadBalancedExchangeFilterFunction + } + if (!hasLoadBalancedFilter) { + val loadBalancedExchangeFilterFunction = appContext.getBean(loadBalancedFilterClass) + filters.add(loadBalancedExchangeFilterFunction) + } + } +} diff --git a/spring/src/main/kotlin/me/ahoo/coapi/spring/WebClientFactoryBean.kt b/spring/src/main/kotlin/me/ahoo/coapi/spring/WebClientFactoryBean.kt index fa5f632..5861af9 100644 --- a/spring/src/main/kotlin/me/ahoo/coapi/spring/WebClientFactoryBean.kt +++ b/spring/src/main/kotlin/me/ahoo/coapi/spring/WebClientFactoryBean.kt @@ -13,57 +13,5 @@ package me.ahoo.coapi.spring -import org.springframework.beans.factory.FactoryBean -import org.springframework.cloud.client.loadbalancer.reactive.LoadBalancedExchangeFilterFunction -import org.springframework.context.ApplicationContext -import org.springframework.context.ApplicationContextAware -import org.springframework.web.reactive.function.client.ExchangeFilterFunction -import org.springframework.web.reactive.function.client.WebClient - -/** - * @see org.springframework.cloud.client.loadbalancer.reactive.LoadBalancedExchangeFilterFunction - */ -class WebClientFactoryBean(private val definition: CoApiDefinition) : - FactoryBean, - ApplicationContextAware { - companion object { - private val loadBalancedFilterClass = LoadBalancedExchangeFilterFunction::class.java - } - - private lateinit var applicationContext: ApplicationContext - override fun getObject(): WebClient { - val clientBuilder = applicationContext.getBean(WebClient.Builder::class.java) - clientBuilder.baseUrl(definition.baseUrl) - val filters = buildList { - definition.filters.forEach { filterName -> - val filter = applicationContext.getBean(filterName, ExchangeFilterFunction::class.java) - add(filter) - } - definition.filterTypes.forEach { filterType -> - val filter = applicationContext.getBean(filterType) - add(filter) - } - if (definition.loadBalanced) { - val hasLoadBalancedFilter = any { filter -> - filter is LoadBalancedExchangeFilterFunction - } - if (!hasLoadBalancedFilter) { - val loadBalancedExchangeFilterFunction = applicationContext.getBean(loadBalancedFilterClass) - add(loadBalancedExchangeFilterFunction) - } - } - } - filters.distinct().forEach { - clientBuilder.filter(it) - } - return clientBuilder.build() - } - - override fun getObjectType(): Class<*> { - return WebClient::class.java - } - - override fun setApplicationContext(applicationContext: ApplicationContext) { - this.applicationContext = applicationContext - } -} +class WebClientFactoryBean(definition: CoApiDefinition) : + AbstractWebClientFactoryBean(definition)