说明
有时候存在这么一种需求,openfeign 调用的时候需要动态变化请求地址
1. 实现拦截
@Slf4j
@Configuration
public class FeignInterceptor implements RequestInterceptor {
@Resource
private FeignServiceUrlConfig feignServiceUrlConfig;
@Override
public void apply(RequestTemplate template) {
Target<?> target = template.feignTarget();
Map<String, String> urlMap = feignServiceUrlConfig.getUrl();
if(!CollectionUtils.isEmpty(urlMap) && urlMap.containsKey(target.name())){
String url = urlMap.get(target.name());
if (StringUtils.hasLength(url)) {
log.info("获取的动态 feign 服务配置信息,service-name: {} ,url : {}",target.name(),url);
template.target(urlMap.get(target.name()));
}else {
// 避免 从 URL 到 服务发现的时候调用失败
Target<?> hardCodedTarget = new Target.HardCodedTarget(target.type(),target.name());
template.feignTarget(hardCodedTarget);
}
}
}
}
2. 服务配置
@Data
@Configuration
// 配合 nacos 进行动态刷新配置
@RefreshScope
@ConfigurationProperties("feign.service")
public class FeignServiceUrlConfig {
/**
* key微服务名,value服务地址
*/
private Map<String, String> url;
}
3. 覆盖 feign 原有的 SynchronousMethodHandler
主要修改代码
Response response = null;
long start = System.nanoTime();
try {
Target<?> target = template.feignTarget();
String url = target.url();
if (StringUtils.hasLength(url) ) {
String name = target.name();
int findIndex = url.indexOf(name);
// 默认是 url 中包含 name, 默认情况下,url是http://nacos-demo/xxxxm,name是nacos-demo
if (findIndex > 0) {
if (client instanceof FeignBlockingLoadBalancerClient) {
// 这里的 FeignBlockingLoadBalancerClient 装饰了最原始的 client
response = ((FeignBlockingLoadBalancerClient)client).getDelegate().execute(request, options);
}
}
}
if (Objects.isNull(response)) {
response = client.execute(request, options);
}
// ensure the request is set. TODO: remove in Feign 12
response = response.toBuilder()
.request(request)
.requestTemplate(template)
.build();
} catch (IOException e) {
if (logLevel != Logger.Level.NONE) {
logger.logIOException(metadata.configKey(), logLevel, e, elapsedTime(start));
}
throw errorExecuting(request, e);
}
4. 配置文件
spring:
application:
name: springboot-openfeign
cloud:
loadbalancer:
retry:
enabled: true
enabled: true
nacos:
discovery:
server-addr: 127.0.0.1:8848
enabled: true
namespace:
username: nacos
password: nacos
config:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
file-extension: yaml
extension-configs:
- dataId: springboot-common.yaml
refresh: true
group: DEFAULT_GROUP
# username: ${spring.cloud.nacos.discovery.username}
# password: ${spring.cloud.nacos.discovery.password}
namespace: ${spring.cloud.nacos.discovery.namespace}
springboot-common.yaml
demo:
config: nacos
feign:
service:
url:
# 微服务名
nacos-demo: http://127.0.0.1:8080
5. feign 调用
@FeignClient(value = "nacos-demo")
public interface EngineServiceApi {
/**
* 获取引擎详情
* @param param
* @return
*/
@PostMapping("/feign/engine/getInfo")
Object info(@RequestBody EngineIdDTO param);
}
- 本文链接: http://maltose.top/archives/实现openfeign动态修改url
- 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!