如何用域名做网站访问,胖子马wordpress模板:q8免费版,做文员的网站知乎,wordpress移植主题typecho我的目的是参照原本openfeign的注解#xff0c;但是我想实现每个外部服务的URL可以自己指定生成的规则。
自定义EnableMyFeignClients
自定义MyImportBeanDefinitionRegistrar#xff0c;更改获取URL的逻辑。这个应该是个可行的方式#xff0c;但是RIBBON的视线方式应该会…我的目的是参照原本openfeign的注解但是我想实现每个外部服务的URL可以自己指定生成的规则。
自定义EnableMyFeignClients
自定义MyImportBeanDefinitionRegistrar更改获取URL的逻辑。这个应该是个可行的方式但是RIBBON的视线方式应该会更好之后再看。 //TODO modify here to set the rule to get the url factoryBean.setUrl(getUrl(beanFactory, attributes));
自定义MyFeignClient
package com.example.demospringboot3.FactoryBean;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;import org.springframework.context.annotation.Import;Retention(RetentionPolicy.RUNTIME)
Target(ElementType.TYPE)
Documented
Import(MyImportBeanDefinitionRegistrar.class)
public interface EnableMyFeignClients {String[] value() default {};String[] basePackages() default {};Class?[] basePackageClasses() default {};Class?[] defaultConfiguration() default {};Class?[] clients() default {};}package com.example.demospringboot3.FactoryBean;import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.beans.factory.config.*;
import org.springframework.beans.factory.support.*;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.FeignClientFactoryBean;
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.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.*;//注意这里不能加注解要通过Import导入进去。
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware {Overridepublic void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {registerFeignClients(metadata, registry);通过工具类生成一个bd只是这个Db对象比较纯洁没有绑定任何类//BeanDefinitionBuilder beanDefinitionBuilder BeanDefinitionBuilder.genericBeanDefinition();为什么要转成GenericBeanDefinition这种类型。因为GenericBeanDefinition有更多修改bd属性的方法。后面我会介绍为什么要修改属性。//GenericBeanDefinition beanDefinition (GenericBeanDefinition) beanDefinitionBuilder.getBeanDefinition();//这里很重要。getConstructorArgumentValues是为了获取该bd的所有构造方法因为我们重写了有参构造方法所有我们需要带参数过去不然spring没法帮我们实例化addGenericArgumentValue是添加参数该代码会执行两步第一步是匹配对应的构造方法第二步是实例化。//beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(UserServiceTestInterface.class.getName());因为代理对象类型的实例化的时候走的是代理类的构造方法//beanDefinition.setBeanClass(MyFactoryBean.class);注册bd//registry.registerBeanDefinition(userServiceTest, beanDefinition);}private void registerFeignClients(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {//扫描指定的包下包含MyFeignClient注解的接口LinkedHashSetBeanDefinition candidateComponents new LinkedHashSet();MapString, Object attrs metadata.getAnnotationAttributes(EnableMyFeignClients.class.getName());final Class?[] clients attrs null ? null : (Class?[]) attrs.get(clients);if (clients null || clients.length 0) {ClassPathScanningCandidateComponentProvider scanner getScanner();scanner.setResourceLoader(this.resourceLoader);scanner.addIncludeFilter(new AnnotationTypeFilter(MyFeignClient.class));SetString basePackages getBasePackages(metadata);for (String basePackage : basePackages) {candidateComponents.addAll(scanner.findCandidateComponents(basePackage));}} else {for (Class? clazz : clients) {candidateComponents.add(new AnnotatedGenericBeanDefinition(clazz));}}for (BeanDefinition candidateComponent : candidateComponents) {if (candidateComponent instanceof AnnotatedBeanDefinition) {//获取包含MyFeignClient注解的接口 的各项参数AnnotatedBeanDefinition beanDefinition (AnnotatedBeanDefinition) candidateComponent;AnnotationMetadata annotationMetadata beanDefinition.getMetadata();Assert.isTrue(annotationMetadata.isInterface(), FeignClient can only be specified on an interface);MapString, Object attributes annotationMetadata.getAnnotationAttributes(MyFeignClient.class.getCanonicalName());String name getClientName(attributes);registerFeignClient(registry, annotationMetadata, attributes);}}}private void registerFeignClient(BeanDefinitionRegistry registry, AnnotationMetadata annotationMetadata,MapString, Object attributes) {String className annotationMetadata.getClassName();Class clazz ClassUtils.resolveClassName(className, null);ConfigurableBeanFactory beanFactory registry instanceof ConfigurableBeanFactory? (ConfigurableBeanFactory) registry : null;String contextId getContextId(beanFactory, attributes);String name getName(attributes);FeignClientFactoryBean factoryBean new FeignClientFactoryBean();factoryBean.setBeanFactory(beanFactory);factoryBean.setName(name);factoryBean.setContextId(contextId);factoryBean.setType(clazz);factoryBean.setRefreshableClient(Boolean.FALSE);BeanDefinitionBuilder definition BeanDefinitionBuilder.genericBeanDefinition(clazz, () - {//TODO modify here to set the rule to get the urlfactoryBean.setUrl(getUrl(beanFactory, attributes));factoryBean.setPath(getPath(beanFactory, attributes));factoryBean.setDecode404(Boolean.parseBoolean(String.valueOf(attributes.get(decode404))));Object fallback attributes.get(fallback);if (fallback ! null) {factoryBean.setFallback(fallback instanceof Class ? (Class?) fallback: ClassUtils.resolveClassName(fallback.toString(), null));}Object fallbackFactory attributes.get(fallbackFactory);if (fallbackFactory ! null) {factoryBean.setFallbackFactory(fallbackFactory instanceof Class ? (Class?) fallbackFactory: ClassUtils.resolveClassName(fallbackFactory.toString(), null));}return factoryBean.getObject();});definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);definition.setLazyInit(true);//validate(attributes);AbstractBeanDefinition beanDefinition definition.getBeanDefinition();beanDefinition.setAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE, className);beanDefinition.setAttribute(feignClientsRegistrarFactoryBean, factoryBean);// has a default, wont be nullboolean primary (Boolean) attributes.get(primary);beanDefinition.setPrimary(primary);String[] qualifiers getQualifiers(attributes);if (ObjectUtils.isEmpty(qualifiers)) {qualifiers new String[]{contextId FeignClient};}BeanDefinitionHolder holder new BeanDefinitionHolder(beanDefinition, className, qualifiers);BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);//registerOptionsBeanDefinition(registry, contextId);}private String[] getQualifiers(MapString, Object client) {if (client null) {return null;}ListString qualifierList new ArrayList(Arrays.asList((String[]) client.get(qualifiers)));qualifierList.removeIf(qualifier - !StringUtils.hasText(qualifier));if (qualifierList.isEmpty() getQualifier(client) ! null) {qualifierList Collections.singletonList(getQualifier(client));}return !qualifierList.isEmpty() ? qualifierList.toArray(new String[0]) : null;}private String getQualifier(MapString, Object client) {if (client null) {return null;}String qualifier (String) client.get(qualifier);if (StringUtils.hasText(qualifier)) {return qualifier;}return null;}private String getUrl(ConfigurableBeanFactory beanFactory, MapString, Object attributes) {String url resolve(beanFactory, (String) attributes.get(url));return getUrl(url);}private String getPath(ConfigurableBeanFactory beanFactory, MapString, Object attributes) {String path resolve(beanFactory, (String) attributes.get(path));return getPath(path);}static String getName(String name) {if (!StringUtils.hasText(name)) {return ;}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;}static String getUrl(String 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;}static String getPath(String 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;}private String getContextId(ConfigurableBeanFactory beanFactory, MapString, Object attributes) {String contextId (String) attributes.get(contextId);if (!StringUtils.hasText(contextId)) {return getName(attributes);}contextId resolve(beanFactory, contextId);return getName(contextId);}/* for testing */ String getName(MapString, Object attributes) {return getName(null, attributes);}String getName(ConfigurableBeanFactory beanFactory, MapString, 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(beanFactory, name);return getName(name);}private String resolve(ConfigurableBeanFactory beanFactory, String value) {if (StringUtils.hasText(value)) {if (beanFactory null) {return this.environment.resolvePlaceholders(value);}BeanExpressionResolver resolver beanFactory.getBeanExpressionResolver();String resolved beanFactory.resolveEmbeddedValue(value);if (resolver null) {return resolved;}Object evaluateValue resolver.evaluate(resolved, new BeanExpressionContext(beanFactory, null));if (evaluateValue ! null) {return String.valueOf(evaluateValue);}return null;}return value;}private String getClientName(MapString, Object client) {if (client null) {return null;}String value (String) client.get(contextId);if (!StringUtils.hasText(value)) {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 Environment environment;private ResourceLoader resourceLoader;Overridepublic void setEnvironment(Environment environment) {this.environment environment;}Overridepublic void setResourceLoader(ResourceLoader resourceLoader) {this.resourceLoader resourceLoader;}protected SetString getBasePackages(AnnotationMetadata importingClassMetadata) {MapString, Object attributes importingClassMetadata.getAnnotationAttributes(EnableFeignClients.class.getCanonicalName());SetString 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;}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;}};}
}package com.example.demospringboot3.FactoryBean;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;import org.springframework.core.annotation.AliasFor;Target(ElementType.TYPE)
Retention(RetentionPolicy.RUNTIME)
Documented
Inherited
public interface MyFeignClient {AliasFor(name)String value() default ;String contextId() default ;AliasFor(value)String name() default ;DeprecatedString qualifier() default ;String[] qualifiers() default {};String url() default ;/*** return whether 404s should be decoded instead of throwing FeignExceptions*/boolean decode404() default false;Class?[] configuration() default {};Class? fallback() default void.class;Class? fallbackFactory() default void.class;String path() default ;boolean primary() default true;}使用
启动类加上
EnableMyFeignClients(basePackages {com.example}) package com.example.demospringboot3.openfeign;import com.example.demospringboot3.FactoryBean.MyFeignClient;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;MyFeignClient(name baiduMyFeignClient, url http://127.0.0.1:8888)
public interface BaiduMyFeignClient {RequestMapping(/test)void getMy1();
}