天天看点

Feign的底层原理1 @EnableFeignClients2 根据接口上的注解创建RequestTemplate3 发送请求

Feign的底层原理

  • 1 @EnableFeignClients
  • 2 根据接口上的注解创建RequestTemplate
  • 3 发送请求

1 @EnableFeignClients

这个注解标注在springboot的启动类上,作用是开启feign接口扫描

Feign的底层原理1 @EnableFeignClients2 根据接口上的注解创建RequestTemplate3 发送请求

FeignClientsRegistrar.registerFeignClients()扫描被@FeignClient标识的接口生成代理类

public void registerFeignClients(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        LinkedHashSet<BeanDefinition> candidateComponents = new LinkedHashSet();
        Map<String, Object> attrs = metadata.getAnnotationAttributes(EnableFeignClients.class.getName());
        new AnnotationTypeFilter(FeignClient.class);
        Class<?>[] clients = attrs == null ? null : (Class[])((Class[])attrs.get("clients"));
        if (clients != null && clients.length != 0) {
            Class[] var13 = clients;
            int var15 = clients.length;

            for(int var17 = 0; var17 < var15; ++var17) {
                Class<?> clazz = var13[var17];
                candidateComponents.add(new AnnotatedGenericBeanDefinition(clazz));
            }
        } else {
            ClassPathScanningCandidateComponentProvider scanner = this.getScanner();
            scanner.setResourceLoader(this.resourceLoader);
            scanner.addIncludeFilter(new AnnotationTypeFilter(FeignClient.class));
            Set<String> basePackages = this.getBasePackages(metadata);
            Iterator var9 = basePackages.iterator();

            while(var9.hasNext()) {
                String basePackage = (String)var9.next();
                candidateComponents.addAll(scanner.findCandidateComponents(basePackage));
            }
        }

        Iterator var14 = candidateComponents.iterator();

        while(var14.hasNext()) {
            BeanDefinition candidateComponent = (BeanDefinition)var14.next();
            if (candidateComponent instanceof AnnotatedBeanDefinition) {
                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 = this.getClientName(attributes);
                this.registerClientConfiguration(registry, name, attributes.get("configuration"));
                this.registerFeignClient(registry, annotationMetadata, attributes);
            }
        }

    }
           

2 根据接口上的注解创建RequestTemplate

当controller调用feign代理类时,代理类会调用SynchronousMethodHandler.invoke()创建RequestTemplate(url、requestMethod、body)

3 发送请求

接着通过RequestTemplate创建Request,然后client(HttpClient、OkHttp、URLConnection)使用Request发送请求

继续阅读