Spring Cloud:三【详细】

目录

Http客户端Feign

Feign的使用

Feign自定义配置

第一种方式

第二种方式

Feign的优化

Feign最佳实践方式

实现一

实现二


Http客户端Feign

RestTemplate缺点是,url不统一,编写困难,可读性差,参数复杂难以维护。

这时我们可以使用Feign来代替RestTemplate。

Feign是一个声明式的http客户端。

Feign的使用

1、引入依赖spring-cloud-starter-openfeign

        
            org.springframework.cloud
            spring-cloud-starter-openfeign
        

2、在启动类上添加注解@EnableFeignClients

3、定义Feign接口

@FeignClient("user-server")
public interface UserClient {
    @GetMapping("/user/{id}")
    User findById(@PathVariable("id")Long id);
}

4、修改Service类中的代码

@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private userClient userClient;
    
    public Order queryOrderById(Long orderId){
        Order order = orderMapper.findById(orderId);
        Long userId = order.getUserId();
        User user = userClient.getById(userId);
        order.setUser(user);
        return order;
    }
}

访问地址发现可以正常调用其他模块的方法。

Spring Cloud:三【详细】_第1张图片

需要注意的是Feign内部也是实现了负载均衡。内部集成了Ribbon

Spring Cloud:三【详细】_第2张图片

Feign自定义配置

Feign可以使用自定义配置去覆盖原始默认配置。可以修改的配置如下图

Spring Cloud:三【详细】_第3张图片

通常我们只需要修改日志级别(默认为NONE,什么也不打印)

第一种方式

修改配置文件

feign:
  client:
    config:
      default: #defaule就是全局配置,如果是写具体服务名,则是针对某个微服务的配置
        loggerLevel: FULL

除了打印SQL语句还打印了其他信息

Spring Cloud:三【详细】_第4张图片

第二种方式

添加配置类

public class FeignClientConfiguration {
    @Bean
    public Logger.Level feignLogLevel(){
        return Logger.Level.BASIC;
    }
}

不需要添加配置注解。如果在启动类上添加如下信息,表示全局生效

@EnableFeignClients(defaultConfiguration = FeignClientConfiguration.class)

如果在Client类上添加如下信息,表示局部生效

@FeignClient(value = "user-server",configuration= FeignClientConfiguration.class)
public interface UserClient {
    @GetMapping("/user/{id}")
    User findById(@PathVariable("id")Long id);
}

Feign的优化

Feign的优化点在于更换默认使用的底层客户端实现,默认使用是URLConnection,它不支持连接池。

可以使用以下两种客户端实现

  • HttpClient:支持连接池
  • OKHttp:支持连接池

其次优化点在于日志打印,一般我们不需要打印任何多余的日志,日志级别采用NONE即可,在调试的时候可以选择BASIC。

更改底层客户端实现:

引入依赖,去配置文件中配置连接池


  io.github.openfeign
  feign-httpclient
feign:
  client:
    config:
      default: #defaule就是全局配置,如果是写具体服务名,则是针对某个微服务的配置
        loggerLevel: NONE
  httpclient:
    enabled: true # 引入依赖后,需要手动配置开启httpClient
    max-connections: 200 # 最大连接数
    max-connections-per-route: 50 # 每个路径最大连接数

Feign最佳实践方式

一:由于Client就是发送Http请求所以请求路径和Controller的完全一样,因此给Client和Controller定义统一接口,让Client和Controller去继承和实现这个接口。所有的方法都写在父类接口中。

Spring Cloud:三【详细】_第5张图片

二:将FeignClient抽取为独立模块,把接口有关的POJO和默认配置放入独立模块中,其他服务需要调用Client时直接引入依赖调用

Spring Cloud:三【详细】_第6张图片

缺点:当模块A只需要模块B中的一两个方法时,仍然需要将所有方法都引入模块A中。

实现一

首先创建一个模块里面定义API接口

Spring Cloud:三【详细】_第7张图片

public interface UserAPI {
    @GetMapping("/user/{id}")
    User findById(@PathVariable("id")Long id);
}

在订单模块下引入feign-api模块,并编写Client类


  com.zmt
  feign-api
  1.0
@FeignClient("user-server")
public interface UserClient extends UserAPI {
}

在用户模块下引入fegin-api依赖并编写Controller类

@RestController
@RequestMapping("/user")
public class UserController implements UserAPI {

    @Autowired
    private UserService userService;

    @Override
    public User findById(Long id) {
        return null;
    }
}

缺点:耦合度高、父接口中的参数列表中的映射关系不会被继承

实现二

仍然是创建一个feign-api模块,将其他模块中的Client类移动到feign-api模块中,其次移动相关配置类与实体类

Spring Cloud:三【详细】_第8张图片

在订单模块中引入feign-api模块

        
            xxxxx
            feign-api
            1.0
        

将原来模块中文件导入修改为feign-api中的路径即可

但是有一个问题,在订单模块中无法注入UserClient对象,因为OrderApplication中无法扫描另一个模块中的包。为了解决这个问题,有两种方案,一种是在启动类上添加包扫描,另一种是在启动类上指定客户端字节码文件。

// 方法一
@EnableFeignClients(basePackages = "cn.itcast.feign.clients")
// 方法二(推荐)
@EnableFeignClients(clients = {UserClient.class})

启动观察:

Spring Cloud:三【详细】_第9张图片

你可能感兴趣的:(spring,cloud,spring,后端)