springboot~openfeign从此和httpClient说再见

在微服务设计里,服务之间的调用是很正常的,通常我们使用httpClient来实现对远程资源的调用,而这种方法需要知识服务的地址,业务接口地址等,而且需要等他开发完成后你才可以去调用它,这对于集成开发来说,不是什么好事 ,产生了A业务与B业务的强依赖性,那么我们如何进行解耦呢,答案就是openfeign框架,它与是springcloudy里的一部分。

1 添加包引用

'org.springframework.cloud:spring-cloud-starter-openfeign',

注意如果你没有引用springcloudy版本人有太多,需要先声明它

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

2 定义profile相关配置

//默认的一些文件路径的配置
sourceSets {
    integTest {
        java.srcDir file('src/test/java')
        resources.srcDir file('src/test/resources')
    }
}

task integTest(type: Test) {
    testClassesDirs = sourceSets.test.output.classesDirs
    classpath = sourceSets.test.runtimeClasspath
}

3 定义服务接口,定义伪方法,就是服务里的方法,你要知识方法参数和它的返回值,实现不用管,只在单元测试里MOCK就可以

package test.lind.javaLindDay.feignClientDemo;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.context.annotation.Profile;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * 模拟其他服务.
 */
@Profile("!integTest")
@FeignClient(name = "serviceName")
public interface MockClient {
  @GetMapping(path = "/balanceSheet/{clientCode}")
  String balanceSheet(String clientCode);
}

4 Profile的作用

profile就是环境变量,你在类上通过ActiveProfile去激活它,在使用它时,有过Profile注解来使用上,上面代码中MockClient对象不能在integTest环境下使用。

5 添加MOCK实现,它是自动注入的,所以声明@Bean注解

package test.lind.javaLindDay;

import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import test.lind.javaLindDay.feignClientDemo.MockClient;

@Configuration
@Profile("integTest")
public class MockClientTest {
  @Bean
  public MockClient mockClient() {
    MockClient client = mock(MockClient.class);
    when(client.balanceSheet(
        anyString()))
        .thenReturn("OK");
    return client;
  }
}

6 添加单元测试,注意在单元测试上一定要指定它的环境变量

package test.lind.javaLindDay;

import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import test.lind.javaLindDay.feignClientDemo.MockClient;

@RunWith(SpringRunner.class)
@SpringBootTest
//指定profile环境
@ActiveProfiles("integTest")
public class JavaLindDayApplicationTests {

  @Autowired
  MockClient mockClient;

  @Test
  public void testMockClient() {
    assertEquals(mockClient.balanceSheet("OK"), "OK");
  }
}

运行测试后,MockClient将会被注入,它将使用Mock实现类,因为只有Mock实现类的Profile是指向integtest环境的。

有了openfeign,以后开发服务对服务调用就可以解耦了!

### Spring Boot 中 OpenFeign 的使用指南 #### 1. 添加依赖 为了在 Spring Boot 项目中使用 OpenFeign 功能,需要引入 `spring-cloud-starter-openfeign` 依赖。如果计划使用特定的 HTTP 客户端实现(如 Apache HttpClient 或 OkHttp),还需要额外添加对应的依赖。 以下是 Maven 配置示例: ```xml <dependencies> <!-- Spring Cloud OpenFeign --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!-- 可选:Apache HttpClient 支持 --> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-hc5</artifactId> </dependency> <!-- 可选:OkHttp 支持 --> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-okhttp</artifactId> </dependency> </dependencies> ``` 通过上述配置即可完成基础依赖的引入[^3]。 --- #### 2. 启用 Feign 客户端 要在 Spring Boot 应用程序中启用 OpenFeign,需在主类或任意配置类上添加注解 `@EnableFeignClients`。此注解会扫描指定包路径下的接口并将其注册为 Feign 客户端。 示例如下: ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication @EnableFeignClients(basePackages = "com.example.clients") // 指定 Feign 接口所在的包路径 public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } ``` --- #### 3. 创建 Feign 客户端接口 创建一个带有 `@FeignClient` 注解的接口,用于定义远程服务的 API 调用方法。该注解的主要属性包括 `name` `url`,分别表示目标服务名称服务地址。 示例如下: ```java import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; @FeignClient(name = "example-service", url = "https://api.example.com") public interface ExampleServiceClient { @GetMapping("/data") String getData(@RequestParam("key") String key); } ``` 在此示例中,`ExampleServiceClient` 是一个 Feign 客户端接口,它可以通过 GET 请求访问 `/data` 端点,并传递查询参数 `key`[^1]。 --- #### 4. 自定义配置 OpenFeign 提供了多种自定义选项,可通过全局配置或针对单个客户端的方式进行设置。常见的自定义场景包括超时时间、日志级别以及请求拦截器等。 ##### (1) 全局配置 可以在 `application.yml` 文件中定义通用的 Feign 配置: ```yaml feign: client: config: default: # 默认配置适用于所有 Feign 客户端 connect-timeout: 5000 # 连接超时时间(毫秒) read-timeout: 10000 # 响应读取超时时间(毫秒) logger-level: full # 日志记录级别(basic, headers, full) ``` ##### (2) 单个客户端配置 对于某些特殊需求,可为某个具体的 Feign 客户端单独定义配置类。例如: ```java import feign.Logger; import feign.RequestInterceptor; import feign.codec.ErrorDecoder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class FeignConfig { @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; // 设置日志级别为 FULL } @Bean RequestInterceptor requestInterceptor() { return template -> template.header("Authorization", "Bearer token"); // 添加授权头 } @Bean ErrorDecoder errorDecoder() { return (methodKey, response) -> new RuntimeException("Custom error handling logic"); } } ``` 然后,在 `@FeignClient` 注解中引用此配置类: ```java @FeignClient(name = "example-service", configuration = FeignConfig.class) public interface ExampleServiceClient { ... } ``` --- #### 5. 整合服务发现与负载均衡 当结合 Spring Cloud 的服务发现组件(如 Eureka)时,无需显式指定 URL 属性。此时,`name` 将作为服务名被解析到具体的服务实例列表中,而 Ribbon 则负责执行负载均衡策略。 示例如下: ```java @FeignClient(name = "user-service") // 不再需要指定 url 属性 public interface UserServiceClient { @GetMapping("/users/{id}") User getUserById(@PathVariable("id") Long id); } ``` 在这种情况下,`user-service` 对应的是注册中心中的微服务名称。 --- #### 6. 测试与运行 启动应用程序后,可以直接注入 Feign 客户端并通过其调用远程服务的方法。例如: ```java @RestController @RequestMapping("/test") public class TestController { private final ExampleServiceClient exampleServiceClient; public TestController(ExampleServiceClient exampleServiceClient) { this.exampleServiceClient = exampleServiceClient; } @GetMapping("/fetch-data") public ResponseEntity<String> fetchData(@RequestParam("key") String key) { try { String result = exampleServiceClient.getData(key); // 调用远程服务 return ResponseEntity.ok(result); } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage()); } } } ``` --- ### 总结 本文介绍了如何在 Spring Boot 中使用 OpenFeign 实现声明式的 RESTful Web Service 调用。主要内容涵盖了依赖管理、客户端定义、自定义配置以及与服务发现负载均衡的整合[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值