美文网首页
如何注入OpenFeign对象

如何注入OpenFeign对象

作者: Alen_ab56 | 来源:发表于2022-12-11 20:12 被阅读0次

Feign的用法

1.引入依赖 openfeign

<dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-openfeign</artifactId>

        </dependency>

2.在启动类上加 @EnableFeignClients("Feign接口所在的包名")。

3.编写Feign接口,在接口上加@FeignClient("被调用的服务名")。

4.在Feign接口中编写方法(对应提供者的方法),方法可以使用SpringMVC的注解。

5.注入接口对象,通过方法实现远程调用。

————————————————

如果有多个包,第二步需要配置多个包名

@EnableFeignClient的底层逻辑是:

@Import FeignClientsRegistrar

这个Class 的定义:

class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar,

ResourceLoaderAware,EnvironmentAware {

核心是解析@FeignClient注解的class,注册到spring工厂中

public void registerFeignClients(AnnotationMetadata metadata,

BeanDefinitionRegistry registry) {

ClassPathScanningCandidateComponentProvider scanner = getScanner();

scanner.setResourceLoader(this.resourceLoader);

SetbasePackages;

Mapattrs = 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 SetclientClasses =new HashSet<>();

basePackages =new HashSet<>();

for (Classclazz :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) {

SetcandidateComponents =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");

Mapattributes =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);

}

public static void registerBeanDefinition(

BeanDefinitionHolder definitionHolder,BeanDefinitionRegistry registry)

throws BeanDefinitionStoreException {

// Register bean definition under primary name.

  String beanName = definitionHolder.getBeanName();

registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

// Register aliases for bean name, if any.

  String[]aliases = definitionHolder.getAliases();

if (aliases !=null) {

for (String alias :aliases) {

registry.registerAlias(beanName,alias);

}

}

}

相关文章

网友评论

      本文标题:如何注入OpenFeign对象

      本文链接:https://www.haomeiwen.com/subject/nizfqdtx.html