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

修改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 RibbonClientsConfigurationRegistgrarprivate ResourceLoader resourceLoader; private Environment environment; private String applicationName; public FeignClientsRegistrar() {}@Overridepublic void setResourceLoader(ResourceLoader resourceLoader) {this.resourceLoader = resourceLoader; }@Overridepublic 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 = https://www.it610.com/article/{}",applicationName); registerDefaultConfiguration(metadata, registry); registerFeignClients(metadata, registry); }private void registerDefaultConfiguration(AnnotationMetadata metadata,BeanDefinitionRegistry registry) {Map 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 basePackages; Map 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 clientClasses = new HashSet<>(); basePackages = new HashSet<>(); for (Class clazz : clients) {basePackages.add(ClassUtils.getPackageName(clazz)); clientClasses.add(clazz.getCanonicalName()); }AbstractClassTestingTypeFilter filter = new AbstractClassTestingTypeFilter() {@Overrideprotected 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 candidateComponents = scanner.findCandidateComponents(basePackage); for (BeanDefinition candidateComponent : candidateComponents) {if (candidateComponent instanceof AnnotatedBeanDefinition) {// verify annotated class is an interfaceAnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent; AnnotationMetadata annotationMetadata = https://www.it610.com/article/beanDefinition.getMetadata(); Assert.isTrue(annotationMetadata.isInterface(),"@FeignClient can only be specified on an interface"); Map 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 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 nullbeanDefinition.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 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 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 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 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) {@Overrideprotected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {boolean isCandidate = false; if (beanDefinition.getMetadata().isIndependent()) {if (!beanDefinition.getMetadata().isAnnotation()) {isCandidate = true; }}return isCandidate; }}; }protected Set getBasePackages(AnnotationMetadata importingClassMetadata) {Map attributes = importingClassMetadata.getAnnotationAttributes(EnableFeignClients.class.getCanonicalName()); Set 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 client) {if (client == null) {return null; }String qualifier = (String) client.get("qualifier"); if (StringUtils.hasText(qualifier)) {return qualifier; }return null; }private String getClientName(Map client) {if (client == null) {return null; }return applicationName; /* String value = https://www.it610.com/article/(String) client.get("value"); if (!StringUtils.hasText(value)) {value = https://www.it610.com/article/(String) client.get("name"); }if (!StringUtils.hasText(value)) {value = https://www.it610.com/article/(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()); }@Overridepublic 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 delegates; /*** Creates a new {@link AllTypeFilter} to match if all the given delegates match.** @param delegates must not be {@literal null}.*/public AllTypeFilter(List delegates) {Assert.notNull(delegates, "This argument is required, it must not be null"); this.delegates = delegates; }@Overridepublic 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 = "https://www.it610.com/article/test",method = RequestMethod.GET)@ResponseBodypublic void test(){String url = "http://cyn-admin"; service.buildFeign(url); System.out.println(service.getTestClient().dictList()); }

【如何修改FeginCilent定义的服务名到指定服务】以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

    推荐阅读