这篇文章主要介绍了修改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 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 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() { @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 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 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 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 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) { @Override protected 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 = (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 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; } @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()); }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程之家。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。