springcloud学习笔记之Feign组件

本文详细介绍了Spring Cloud Feign的使用和原理,包括Feign的基本概念、如何在项目中启用Feign、@EnableFeignClients和@FeignClient注解的解析,以及Feign的注册过程。通过源码分析,揭示了Feign如何通过动态代理实现服务调用,并结合Hystrix和Ribbon实现熔断和负载均衡。
摘要由CSDN通过智能技术生成

目录

一、feign简介应用

      1、feign的概念

      2、feign的使用

二、feign原理分析

      1、前言

      2、@EnableFeignClients注解

  2.1、@EnableFeignClients

  2.2、FeignClientsRegistrar类

  2.3、加载feign的配置信息

  2.4、注册FeignClient

  2.5、registerFeignClient

3、@FeignClient注解

    3.1 FeignClient注解使用

    3.2 @FeignClient的属性

    3.3 @FeignClient源码分析

 



一、feign简介应用

      1、feign的概念

             Feign是一个声明性的Web服务客户端。它使编写Web服务客户端变得更容易。feigin是一种模板化,声明式的http客户端,feign可以通过注解绑定到接口上来简化Http请求访问。与当我们访问别的服务端口的时候 大部分使用httpclient等请求进行调用不同,在eureka注册的服务,我们可以使用Feign 声明接口的形式来进行相关服务的调用,并提供了失败回退(其实是Hystrix组件的使用)。Feign只是一个便利的rest框架,简化调用,最后还是通过ribbon在注册服务器中找到服务实例,然后对请求进行分配。

      2、feign的使用

  •        maven依赖          
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
  •      主项目中添加@EnableFeignClients
@SpringBootApplication
//扫描项目下所有使用@FeignClient注解修饰的接口
@EnableFeignClients
@EnableEurekaClient
public class FeignApplication {

	public static void main(String[] args) {

		SpringApplication.run(FeignApplication.class, args);
	}

}
  •    使用feign调用微服务
//使用feignclien注解和SpringMVC相关的常用注解 声明一个feign接口 调用微服务信息
@FeignClient(value = "service-ribbon",url = "https://api.github.com",decode404 = false,
        fallback = MyFallback.class, fallbackFactory = MyFallBackFactory.class )
public interface SayHiFeign {

    @RequestMapping("/hi", method = RequestMethod.GET)
    String sayHi(@RequestParam(name="name",required = true) String name);
}

  如上便完成了使用feign完成别的为服务调用,是不是很简单。点击下载demo源码 feign组件使用demo

二、feign原理分析

      1、前言

                 通过如上的简单介绍我们大致了解了feign的概念以及如何在项目中进行使用,通过上面的观察以及使用,我们发现feign组件在springclound项目中使用是如此只简单:只需在项目的主启动类使用@EnableFeignClients注解,在服务接口类中使用@FeignClient修饰。下面我们就从这两个注解入手揭开feign的神秘面纱(貌似话说的有点大)。

      2、@EnableFeignClients注解

                    为了方便理解,我们在这里先不给出结论,直接从源码中一步一步分析代码,最后再给出结论。

             2.1、@EnableFeignClients

//运行时保留
@Retention(RetentionPolicy.RUNTIME)
//该注解用于修饰描述类、接口(包括注解类型) 或enum声明
@Target(ElementType.TYPE)
//可以生产api doc
@Documented
//这个比较重要使用注解修饰的项目 需要先初始化FeignClientsRegistrar该类 
@Import(FeignClientsRegistrar.class)
public @interface EnableFeignClients {

	//basePackages的别名
	String[] value() default {};

    //指定需要扫描的包名列表
	String[] basePackages() default {};

    //指定需要扫描的class列表信息
	Class<?>[] basePackageClasses() default {};

	//feign调用的配置信息类 该对象非常重要,
    //包含FeignClient需要的重试策略,超时策略,日志等配置,
    //如果某个服务没有设置, 则读取默认的配置。
	Class<?>[] defaultConfiguration() default {};

	//直接指定FeignClient注解修饰的class
	Class<?>[] clients() default {};

      该注解 用来开启 Feign,所以其属性主要是指定要扫描的包名类名 FeignClient列表(value属性,basePackages属性,basePackageClasses属性,clients属性),以及相关的配置信息(defaultConfiguration),这些并非我们关注的重点 在该注解类上有个使用@Import注解引入FeignClientsRegistrar.class 的实体类 其实该类是实现feign调用的部分功能(前期准备)的实现,下面让我们来分析一下

FeignClientsRegistrar类

   2.2、FeignClientsRegistrar类

class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar,
      ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
  

          通过名字可以看出该类是一个注册器,该类实现了 ImportBeanDefinitionRegistrar 通过扫描某个特性的类,将bean注册到IOC中。他的生命周期方法是registerBeanDefinitions ,Spring 通过调用其 registerBeanDefinitions 方法来获取其提供的 bean definition。

//生命周期的方法
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata,
    	BeanDefinitionRegistry registry) {
    //注册feign 相关的特性 配置信息
	registerDefaultConfiguration(metadata, registry);
    //注册FeignClient 对象
	registerFeignClients(metadata, registry);
}

上面开启feign主要分两大部分:

  •  注册feign的配置信息,比如重试机制,日志配置
  •  注册所有使用@FeigenClient修饰的类注册

 2.3、加载feign的配置信息

//注册配置信息
private void registerDefaultConfiguration(AnnotationMetadata metadata,
			BeanDefinitionRegistry registry) {
        //获取EnableFeignClients注解的元数据信息
		Map<String, Object> defaultAttrs = metadata
				.getAnnotationAttributes(EnableFeignClients.class.getName(), true);

        //判断是否存在defaultConfiguration 属性信息
		if (defaultAttrs != null && defaultAttrs.containsKey("defaultConfiguration")) {
			String name;
			if (metadata.hasEnclosingClass()) {
				name = "default." + metadata.getEnclosingClassName();
			}
			else {
				name = "default." + metadata.getClassName();
			}
            //注册defaultConfiguration 对应的属性信息类 ,如果为空则使用默认的配置 
            //FeignAutoConfiguration
            //最终将配置类解析成一个BeanDefinition类注入到spring中
			registerClientConfiguration(registry, name,
					defaultAttrs.get("defaultConfiguration"));
		}
	}
如上主要是从启动类的@EnableFeignClients 中获取defaultConfiguration属性中用户自定义的配置信息,如果没有则使用默认的配置信息类FeignAutoConfiguration,最终将其包装成BeanDefinition类注册到spring容器中(代码比较繁琐,个人只贴到这里)。配置中心主要提供了feign 的功能特性,该配置信息是适用于@FeignClient注解的全局配置,也可以在@FeignClient的configuration属性做单独的配置。该配置主要包含熔断器、失败重试、超时策略、日志配置等。

 2.4、注册FeignClient

   //注册FeigenClient
    public void registerFeignClients(AnnotationMetadata metadata,
                                     BeanDefinitionRegistry registry) {
        //获取类扫描组件
        ClassPathScanningCandidateComponentProvider scanner = getScanner();
        //添加资源加载服务类 提供加载指定目录下的资源信息 便于后面的类扫描
        scanner.setResourceLoader(this.resourceLoader);

        Set<String> basePackages;

        //获取EnableFeignClients注解的属性信息 其中可能包含需要扫描的包名或者class信息
        Map<String, Object> attrs = metadata
                .getAnnotationAttributes(EnableFeignClients.class.getName());
        //创建扫描过滤规则 只扫描包含FeignClient注解修饰的类
        AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(
                FeignClient.class);
        //获取注解中包含client 属性  如果有则不进行包名扫描 直接遍历存在的client 进行注册
        final Class<
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值