如何修改FeginCilent定义的服务名到指定服务

作者:一只猪啊啊 时间:2022-07-05 05:49:05 

修改FeginCilent定义的服务名到指定服务

通过覆盖类来修改对应的服务名,这里将所有的FeginClient对应的服务名都修改好。


package org.springframework.cloud.openfeign;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.AbstractClassTestingTypeFilter;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
* @author Spencer Gibb
* @author Jakub Narloch
* @author Venil Noronha
* @author Gang Li
*/
class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar,
       ResourceLoaderAware, EnvironmentAware {
   private static Logger logger = LoggerFactory.getLogger(FeignClientsRegistrar.class);
   // patterned after Spring Integration IntegrationComponentScanRegistrar
   // and RibbonClientsConfigurationRegistgrar
   private ResourceLoader resourceLoader;
   private Environment environment;
   private String applicationName;
   public FeignClientsRegistrar() {
   }
   @Override
   public void setResourceLoader(ResourceLoader resourceLoader) {
       this.resourceLoader = resourceLoader;
   }
   @Override
   public void registerBeanDefinitions(AnnotationMetadata metadata,
                                       BeanDefinitionRegistry registry) {
       applicationName = environment.getProperty("cover.applicationName");
       if(applicationName == null){
           throw new NullPointerException("cover.baseline.applicationName 未配置 请配置后再启动");
       }
       logger.info("cover.baseline.applicationName 已配置 value = {}",applicationName);
       registerDefaultConfiguration(metadata, registry);
       registerFeignClients(metadata, registry);
   }
   private void registerDefaultConfiguration(AnnotationMetadata metadata,
                                             BeanDefinitionRegistry registry) {
       Map<String, Object> defaultAttrs = metadata
               .getAnnotationAttributes(EnableFeignClients.class.getName(), true);
       if (defaultAttrs != null && defaultAttrs.containsKey("defaultConfiguration")) {
           String name;
           if (metadata.hasEnclosingClass()) {
               name = "default." + metadata.getEnclosingClassName();
           } else {
               name = "default." + metadata.getClassName();
           }
           registerClientConfiguration(registry, name,
                   defaultAttrs.get("defaultConfiguration"));
       }
   }
   public void registerFeignClients(AnnotationMetadata metadata,
                                    BeanDefinitionRegistry registry) {
       ClassPathScanningCandidateComponentProvider scanner = getScanner();
       scanner.setResourceLoader(this.resourceLoader);
       Set<String> basePackages;
       Map<String, Object> attrs = metadata
               .getAnnotationAttributes(EnableFeignClients.class.getName());
       AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(
               FeignClient.class);
       final Class<?>[] clients = attrs == null ? null
               : (Class<?>[]) attrs.get("clients");
       if (clients == null || clients.length == 0) {
           scanner.addIncludeFilter(annotationTypeFilter);
           basePackages = getBasePackages(metadata);
       } else {
           final Set<String> clientClasses = new HashSet<>();
           basePackages = new HashSet<>();
           for (Class<?> clazz : clients) {
               basePackages.add(ClassUtils.getPackageName(clazz));
               clientClasses.add(clazz.getCanonicalName());
           }
           AbstractClassTestingTypeFilter filter = new AbstractClassTestingTypeFilter() {
               @Override
               protected boolean match(ClassMetadata metadata) {
                   String cleaned = metadata.getClassName().replaceAll("\\$", ".");
                   return clientClasses.contains(cleaned);
               }
           };
           scanner.addIncludeFilter(
                   new AllTypeFilter(Arrays.asList(filter, annotationTypeFilter)));
       }
       for (String basePackage : basePackages) {
           Set<BeanDefinition> candidateComponents = scanner
                   .findCandidateComponents(basePackage);
           for (BeanDefinition candidateComponent : candidateComponents) {
               if (candidateComponent instanceof AnnotatedBeanDefinition) {
                   // verify annotated class is an interface
                   AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent;
                   AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();
                   Assert.isTrue(annotationMetadata.isInterface(),
                           "@FeignClient can only be specified on an interface");
                   Map<String, Object> attributes = annotationMetadata
                           .getAnnotationAttributes(
                                   FeignClient.class.getCanonicalName());
                   String name = getClientName(attributes);
                   registerClientConfiguration(registry, name,
                           attributes.get("configuration"));
                   registerFeignClient(registry, annotationMetadata, attributes);
               }
           }
       }
   }
   private void registerFeignClient(BeanDefinitionRegistry registry,
                                    AnnotationMetadata annotationMetadata, Map<String, Object> attributes) {
       String className = annotationMetadata.getClassName();
       BeanDefinitionBuilder definition = BeanDefinitionBuilder
               .genericBeanDefinition(FeignClientFactoryBean.class);
       validate(attributes);
       definition.addPropertyValue("url", getUrl(attributes));
       definition.addPropertyValue("path", getPath(attributes));
       String name = getName(attributes);
       definition.addPropertyValue("name", name);
       definition.addPropertyValue("type", className);
       definition.addPropertyValue("decode404", attributes.get("decode404"));
       definition.addPropertyValue("fallback", attributes.get("fallback"));
       definition.addPropertyValue("fallbackFactory", attributes.get("fallbackFactory"));
       definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
       String alias = name + "FeignClient";
       AbstractBeanDefinition beanDefinition = definition.getBeanDefinition();
       boolean primary = (Boolean) attributes.get("primary"); // has a default, won't be null
       beanDefinition.setPrimary(primary);
       String qualifier = getQualifier(attributes);
       if (StringUtils.hasText(qualifier)) {
           alias = qualifier;
       }
       BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, className,
               new String[]{alias});
       BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
   }
   private void validate(Map<String, Object> attributes) {
       AnnotationAttributes annotation = AnnotationAttributes.fromMap(attributes);
       // This blows up if an aliased property is overspecified
       // FIXME annotation.getAliasedString("name", FeignClient.class, null);
       Assert.isTrue(
               !annotation.getClass("fallback").isInterface(),
               "Fallback class must implement the interface annotated by @FeignClient"
       );
       Assert.isTrue(
               !annotation.getClass("fallbackFactory").isInterface(),
               "Fallback factory must produce instances of fallback classes that implement the interface annotated by @FeignClient"
       );
   }
   /* for testing */ String getName(Map<String, Object> attributes) {
       /*String name = (String) attributes.get("serviceId");
       if (!StringUtils.hasText(name)) {
           name = (String) attributes.get("name");
       }
       if (!StringUtils.hasText(name)) {
           name = (String) attributes.get("value");
       }
       name = resolve(name);
       if (!StringUtils.hasText(name)) {
           return "";
       }*/
       String name = applicationName;
       String host = null;
       try {
           String url;
           if (!name.startsWith("http://") && !name.startsWith("https://")) {
               url = "http://" + name;
           } else {
               url = name;
           }
           host = new URI(url).getHost();
       } catch (URISyntaxException e) {
       }
       Assert.state(host != null, "Service id not legal hostname (" + name + ")");
       return name;
   }
   private String resolve(String value) {
       if (StringUtils.hasText(value)) {
           return this.environment.resolvePlaceholders(value);
       }
       return value;
   }
   private String getUrl(Map<String, Object> attributes) {
       String url = resolve((String) attributes.get("url"));
       if (StringUtils.hasText(url) && !(url.startsWith("#{") && url.contains("}"))) {
           if (!url.contains("://")) {
               url = "http://" + url;
           }
           try {
               new URL(url);
           } catch (MalformedURLException e) {
               throw new IllegalArgumentException(url + " is malformed", e);
           }
       }
       return url;
   }
   private String getPath(Map<String, Object> attributes) {
       String path = resolve((String) attributes.get("path"));
       if (StringUtils.hasText(path)) {
           path = path.trim();
           if (!path.startsWith("/")) {
               path = "/" + path;
           }
           if (path.endsWith("/")) {
               path = path.substring(0, path.length() - 1);
           }
       }
       return path;
   }
   protected ClassPathScanningCandidateComponentProvider getScanner() {
       return new ClassPathScanningCandidateComponentProvider(false, this.environment) {
           @Override
           protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
               boolean isCandidate = false;
               if (beanDefinition.getMetadata().isIndependent()) {
                   if (!beanDefinition.getMetadata().isAnnotation()) {
                       isCandidate = true;
                   }
               }
               return isCandidate;
           }
       };
   }
   protected Set<String> getBasePackages(AnnotationMetadata importingClassMetadata) {
       Map<String, Object> attributes = importingClassMetadata
               .getAnnotationAttributes(EnableFeignClients.class.getCanonicalName());
       Set<String> basePackages = new HashSet<>();
       for (String pkg : (String[]) attributes.get("value")) {
           if (StringUtils.hasText(pkg)) {
               basePackages.add(pkg);
           }
       }
       for (String pkg : (String[]) attributes.get("basePackages")) {
           if (StringUtils.hasText(pkg)) {
               basePackages.add(pkg);
           }
       }
       for (Class<?> clazz : (Class[]) attributes.get("basePackageClasses")) {
           basePackages.add(ClassUtils.getPackageName(clazz));
       }
       if (basePackages.isEmpty()) {
           basePackages.add(
                   ClassUtils.getPackageName(importingClassMetadata.getClassName()));
       }
       return basePackages;
   }
   private String getQualifier(Map<String, Object> client) {
       if (client == null) {
           return null;
       }
       String qualifier = (String) client.get("qualifier");
       if (StringUtils.hasText(qualifier)) {
           return qualifier;
       }
       return null;
   }
   private String getClientName(Map<String, Object> client) {
       if (client == null) {
           return null;
       }
       return applicationName;
     /* String value = (String) client.get("value");
       if (!StringUtils.hasText(value)) {
           value = (String) client.get("name");
       }
       if (!StringUtils.hasText(value)) {
           value = (String) client.get("serviceId");
       }
       if (StringUtils.hasText(value)) {
           return value;
       }
       throw new IllegalStateException("Either 'name' or 'value' must be provided in @"
               + FeignClient.class.getSimpleName());*/
   }
   private void registerClientConfiguration(BeanDefinitionRegistry registry, Object name,
                                            Object configuration) {
       BeanDefinitionBuilder builder = BeanDefinitionBuilder
               .genericBeanDefinition(FeignClientSpecification.class);
       builder.addConstructorArgValue(name);
       builder.addConstructorArgValue(configuration);
       registry.registerBeanDefinition(
               name + "." + FeignClientSpecification.class.getSimpleName(),
               builder.getBeanDefinition());
   }
   @Override
   public void setEnvironment(Environment environment) {
       this.environment = environment;
   }
   /**
    * Helper class to create a {@link TypeFilter} that matches if all the delegates
    * match.
    *
    * @author Oliver Gierke
    */
   private static class AllTypeFilter implements TypeFilter {
       private final List<TypeFilter> delegates;
       /**
        * Creates a new {@link AllTypeFilter} to match if all the given delegates match.
        *
        * @param delegates must not be {@literal null}.
        */
       public AllTypeFilter(List<TypeFilter> delegates) {
           Assert.notNull(delegates, "This argument is required, it must not be null");
           this.delegates = delegates;
       }
       @Override
       public boolean match(MetadataReader metadataReader,
                            MetadataReaderFactory metadataReaderFactory) throws IOException {
           for (TypeFilter filter : this.delegates) {
               if (!filter.match(metadataReader, metadataReaderFactory)) {
                   return false;
               }
           }
           return true;
       }
   }
}

FeginCilent动态服务名调用

工作碰到这个问题,解决后记录一下,废话不多说,直接上代码


@Data
@Configuration
@Import(FeignClientsConfiguration.class)
public class Test {
   private TestService testClient;

//Feign 原生构造器
   Feign.Builder builder;

//创建构造器
   public Test(Decoder decoder, Encoder encoder, Client client, Contract contract) {
       this.builder = Feign.builder()
                           .client(client)
                           .encoder(encoder)
                              .decoder(decoder)
                           .contract(contract);
   }

public void buildFeign(String url) {
       this.testClient = builder.target(TestService.class, url);
   }
}

@RequestMapping(value = "test",method = RequestMethod.GET)
   @ResponseBody
   public void test(){
   String url = "http://cyn-admin";
   service.buildFeign(url);
   System.out.println(service.getTestClient().dictList());
   }

来源:https://blog.csdn.net/qq_37616173/article/details/106056131

标签:FeginCilent,服务名,服务
0
投稿

猜你喜欢

  • Java Gradle项目中的资源正确获取方式

    2022-10-05 09:00:50
  • C#实现的MD5加密功能与用法示例

    2023-06-11 09:08:21
  • Java中StringUtils工具类进行String为空的判断解析

    2022-10-16 06:56:53
  • c#滚动字幕动画窗体制作步骤

    2023-12-06 20:12:58
  • 详解JAVA里面获取map的key和value的方法

    2023-04-27 03:11:50
  • 在实践中了解Java反射机制应用

    2021-06-29 02:40:14
  • Eclipse下编写java程序突然不会自动生成R.java文件和包的解决办法

    2023-11-19 00:24:05
  • java8中Stream的使用以及分割list案例

    2022-08-09 10:08:48
  • 基于C#方法重载的总结详解

    2022-07-29 13:19:46
  • Android开发之图片压缩工具类完整实例

    2023-07-02 10:22:08
  • JAVA中String介绍及常见面试题小结

    2021-11-19 03:38:20
  • Java中一维二维数组的静态和动态初始化

    2022-10-09 11:33:06
  • OpenFeign设置header的三种方式总结

    2023-06-25 19:03:46
  • Java的线程与进程以及线程的四种创建方式

    2022-12-01 14:11:07
  • Java的super关键字与instanceof运算符使用方法

    2022-02-18 10:02:22
  • Java代码块与代码加载顺序原理详解

    2023-06-03 12:56:42
  • MybatisPlus字段类型转换的实现示例

    2022-12-09 22:29:13
  • Android RadarView雷达图(蜘蛛网图)的实现代码

    2022-12-09 21:45:19
  • C#基于基姆拉尔森算法计算指定日期是星期几的方法

    2022-04-28 09:31:25
  • Android自定义Adapter的ListView的思路及代码

    2023-10-21 17:56:16
  • asp之家 软件编程 m.aspxhome.com