Openfeign動態構建client實現同服務serviceId不同instanceId互相呼叫

用户名还没想好發表於2024-05-15

本文基於springcloud2.0.0.RELEASE和eureka

openfeign2.0.4.RELEASE版本:

1 <dependency>
2     <groupId>org.springframework.cloud</groupId>
3     <artifactId>spring-cloud-openfeign-core</artifactId>
4     <version>2.0.4.RELEASE</version>
5 </dependency>

工具類:

 1 import com.netflix.appinfo.ApplicationInfoManager;
 2 import com.netflix.appinfo.InstanceInfo;
 3 import com.netflix.discovery.EurekaClient;
 4 import lombok.Getter;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.cloud.openfeign.FeignClient;
 7 import org.springframework.cloud.openfeign.FeignClientBuilder;
 8 import org.springframework.context.ApplicationContext;
 9 import org.springframework.core.annotation.AnnotationUtils;
10 import org.springframework.stereotype.Component;
11 
12 import javax.annotation.PostConstruct;
13 import javax.annotation.Resource;
14 import java.util.ArrayList;
15 import java.util.List;
16 import java.util.stream.Collectors;
17 
18 @Getter
19 @Component
20 public class DynamicFeignClient {
21 
22   private String serviceId;//一般是xxx-server
23 
24   private String instanceId;//一般是ip:port
25 
26   private InstanceInfo thisInfo;
27 
28   private final FeignClientBuilder feignClientBuilder;
29 
30   @Resource
31   private EurekaClient eurekaClient;
32 
33   public DynamicFeignClient(@Autowired ApplicationContext appContext) {
34     feignClientBuilder = new FeignClientBuilder(appContext);
35   }
36 
37   @PostConstruct
38   public void init() {
39     ApplicationInfoManager applicationInfoManager = eurekaClient.getApplicationInfoManager();
40     serviceId = applicationInfoManager.getEurekaInstanceConfig().getAppname();
41     thisInfo = applicationInfoManager.getInfo();
42 
43     instanceId = thisInfo.getInstanceId();
44   }
45 
46   /*
47    * 返回若干個client,分別對應不同的服務例項
48    * excludeThis=true排除自己
49    * */
50   public <T> List<T> getClientsList(Class<T> type, boolean excludeThis) {
51     FeignClient annotation = AnnotationUtils.findAnnotation(type, FeignClient.class);
52     if (annotation == null) {
53       throw new IllegalArgumentException("缺少@FeignClient註解");
54     }
55     List<InstanceInfo> instances = eurekaClient.getApplications().getInstancesByVirtualHostName(getServiceId());
56     if (excludeThis) {
57       instances = instances.stream().filter(f -> !f.equals(thisInfo)).collect(Collectors.toList());
58     }
59     String path = annotation.path();
60     List<T> ret = new ArrayList<>(instances.size());
61     for (InstanceInfo instance : instances) {
62       String homePageUrl = instance.getHomePageUrl();
63       FeignClientBuilder.Builder<T> builder = feignClientBuilder.forType(type, getServiceId());
64       builder.url(homePageUrl);
65       builder.path(path);
66       ret.add(builder.build());
67     }
68     return ret;
69   }
70 
71   public <T> List<T> getClientsList(Class<T> type) {
72     return getClientsList(type, false);
73   }
74 
75 }

相關文章