|
@@ -1,230 +0,0 @@
|
|
|
-/**
|
|
|
- * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com).
|
|
|
- * <p>
|
|
|
- * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
|
|
- * you may not use this file except in compliance with the License.
|
|
|
- * You may obtain a copy of the License at
|
|
|
- * <p>
|
|
|
- * http://www.gnu.org/licenses/lgpl.html
|
|
|
- * <p>
|
|
|
- * Unless required by applicable law or agreed to in writing, software
|
|
|
- * distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
- * See the License for the specific language governing permissions and
|
|
|
- * limitations under the License.
|
|
|
- */
|
|
|
-package org.springframework.cloud.openfeign;
|
|
|
-
|
|
|
-import lombok.Getter;
|
|
|
-import lombok.NoArgsConstructor;
|
|
|
-import org.springblade.core.cloud.feign.BladeFeignAutoConfiguration;
|
|
|
-import org.springframework.beans.factory.BeanClassLoaderAware;
|
|
|
-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.annotation.ImportBeanDefinitionRegistrar;
|
|
|
-import org.springframework.core.annotation.AnnotatedElementUtils;
|
|
|
-import org.springframework.core.annotation.AnnotationAttributes;
|
|
|
-import org.springframework.core.env.Environment;
|
|
|
-import org.springframework.core.io.support.SpringFactoriesLoader;
|
|
|
-import org.springframework.core.type.AnnotationMetadata;
|
|
|
-import org.springframework.lang.Nullable;
|
|
|
-import org.springframework.util.StringUtils;
|
|
|
-
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
-
|
|
|
-/**
|
|
|
- * feign 自动配置
|
|
|
- *
|
|
|
- * @author L.cm
|
|
|
- */
|
|
|
-@NoArgsConstructor
|
|
|
-public class BladeFeignClientsRegistrar implements ImportBeanDefinitionRegistrar, BeanClassLoaderAware, EnvironmentAware {
|
|
|
- @Getter
|
|
|
- private ClassLoader beanClassLoader;
|
|
|
- @Getter
|
|
|
- private Environment environment;
|
|
|
-
|
|
|
- @Override
|
|
|
- public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
|
|
|
- registerFeignClients(metadata, registry);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void setBeanClassLoader(ClassLoader classLoader) {
|
|
|
- this.beanClassLoader = classLoader;
|
|
|
- }
|
|
|
-
|
|
|
- private void registerFeignClients(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
|
|
|
- List<String> feignClients = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
|
|
|
- // 如果 spring.factories 里为空
|
|
|
- if (feignClients.isEmpty()) {
|
|
|
- return;
|
|
|
- }
|
|
|
- for (String className : feignClients) {
|
|
|
- try {
|
|
|
- Class<?> clazz = beanClassLoader.loadClass(className);
|
|
|
- AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(clazz, FeignClient.class);
|
|
|
- if (attributes == null) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- // 如果已经存在该 bean,支持原生的 Feign
|
|
|
- if (registry.containsBeanDefinition(className)) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- registerClientConfiguration(registry, getClientName(attributes), attributes.get("configuration"));
|
|
|
-
|
|
|
- validate(attributes);
|
|
|
- BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(FeignClientFactoryBean.class);
|
|
|
- definition.addPropertyValue("url", getUrl(attributes));
|
|
|
- definition.addPropertyValue("path", getPath(attributes));
|
|
|
- String name = getName(attributes);
|
|
|
- definition.addPropertyValue("name", name);
|
|
|
-
|
|
|
- // 兼容最新版本的 spring-cloud-openfeign,尚未发布
|
|
|
- StringBuilder aliasBuilder = new StringBuilder(18);
|
|
|
- if (attributes.containsKey("contextId")) {
|
|
|
- String contextId = getContextId(attributes);
|
|
|
- aliasBuilder.append(contextId);
|
|
|
- definition.addPropertyValue("contextId", contextId);
|
|
|
- } else {
|
|
|
- aliasBuilder.append(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);
|
|
|
-
|
|
|
- AbstractBeanDefinition beanDefinition = definition.getBeanDefinition();
|
|
|
-
|
|
|
- // alias
|
|
|
- String alias = aliasBuilder.append("FeignClient").toString();
|
|
|
-
|
|
|
- // has a default, won't be null
|
|
|
- boolean primary = (Boolean)attributes.get("primary");
|
|
|
-
|
|
|
- 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);
|
|
|
-
|
|
|
- } catch (ClassNotFoundException e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Return the class used by {@link SpringFactoriesLoader} to load configuration
|
|
|
- * candidates.
|
|
|
- * @return the factory class
|
|
|
- */
|
|
|
- private Class<?> getSpringFactoriesLoaderFactoryClass() {
|
|
|
- return BladeFeignAutoConfiguration.class;
|
|
|
- }
|
|
|
-
|
|
|
- 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);
|
|
|
- FeignClientsRegistrar.validateFallback(annotation.getClass("fallback"));
|
|
|
- FeignClientsRegistrar.validateFallbackFactory(annotation.getClass("fallbackFactory"));
|
|
|
- }
|
|
|
-
|
|
|
- private 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);
|
|
|
- return FeignClientsRegistrar.getName(name);
|
|
|
- }
|
|
|
-
|
|
|
- private String getContextId(Map<String, Object> attributes) {
|
|
|
- String contextId = (String) attributes.get("contextId");
|
|
|
- if (!StringUtils.hasText(contextId)) {
|
|
|
- return getName(attributes);
|
|
|
- }
|
|
|
-
|
|
|
- contextId = resolve(contextId);
|
|
|
- return FeignClientsRegistrar.getName(contextId);
|
|
|
- }
|
|
|
-
|
|
|
- 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"));
|
|
|
- return FeignClientsRegistrar.getUrl(url);
|
|
|
- }
|
|
|
-
|
|
|
- private String getPath(Map<String, Object> attributes) {
|
|
|
- String path = resolve((String) attributes.get("path"));
|
|
|
- return FeignClientsRegistrar.getPath(path);
|
|
|
- }
|
|
|
-
|
|
|
- @Nullable
|
|
|
- private String getQualifier(@Nullable Map<String, Object> client) {
|
|
|
- if (client == null) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- String qualifier = (String) client.get("qualifier");
|
|
|
- if (StringUtils.hasText(qualifier)) {
|
|
|
- return qualifier;
|
|
|
- }
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- @Nullable
|
|
|
- private String getClientName(@Nullable Map<String, 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 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;
|
|
|
- }
|
|
|
-
|
|
|
-}
|