Skip to content

Commit

Permalink
feat: Split LoadBalancedWebClientFactoryBean (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ahoo-Wang authored Jan 18, 2024
1 parent 14c374c commit db57b0c
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 58 deletions.
4 changes: 2 additions & 2 deletions .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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<WebClient>,
ApplicationContextAware {
protected lateinit var appContext: ApplicationContext

protected open val filterCustomizer: (MutableList<ExchangeFilterFunction>) -> 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<ExchangeFilterFunction> {
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
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright [2022-present] [ahoo wang <ahoowang@qq.com> (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<ExchangeFilterFunction>) -> Unit
get() = { filters ->
val hasLoadBalancedFilter = filters.any { filter ->
filter is LoadBalancedExchangeFilterFunction
}
if (!hasLoadBalancedFilter) {
val loadBalancedExchangeFilterFunction = appContext.getBean(loadBalancedFilterClass)
filters.add(loadBalancedExchangeFilterFunction)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<WebClient>,
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<ExchangeFilterFunction> {
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)

0 comments on commit db57b0c

Please sign in to comment.