如何修改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<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());    }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

爱情从希望开始,也由绝望结束。死心了,

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

相关文章:

你感兴趣的文章:

标签云: