美文网首页
如何注入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