# springcloud-test **Repository Path**: dli001/springcloud-test ## Basic Information - **Project Name**: springcloud-test - **Description**: SpringCloud整合OpenFeign示例 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 3 - **Created**: 2022-08-10 - **Last Updated**: 2022-08-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 遇到的问题 SpringCloud 升级到 2020.4 后,网关Gateway启动不了,没有报错,一直卡住。 只要 @Autowired 注入 OpenFeignClient ,就启动不起来。 ## 升级后环境 ```java SpringCloud版本: 2020.0.4 SpringCloudAlibaba版本: 2021.1 SpringBoot版本: 2.5.7 ``` ## 解决办法 有以下几个需要注意的地方: 1. 注入OpenFeignClient 必须使用 @Lazy 2. FeignClient 必须要异步调用,使用Future方式,不能同步调用,不然会报不能在xxx线程执行的错。读者可以自行尝试下哈。 3. 使用 @EnableFeignClients ,开启 OpenFeign 功能 4. 使用 @EnableAsync 开启异步执行功能,不然加了 @Async 注解也没用哦。 ## 主要的代码示例 ### OpenFeignClient 定义 ```java // 我这里降级啥的都没写哦 @FeignClient(name = "system", decode404 = true) public interface SystemFeignClient { @GetMapping("/test") String test(@RequestParam("id") String id); } ``` ### OpenFeignClien注入示例 ```java // 这个类的作用,是将Client包装一层,在这里做异步处理 @Slf4j @Component public class ClientHolder { @Lazy // 重点:这里必须使用@Lazy @Autowired private SystemFeignClient systemFeignClient; @Async // 重点:这里必须在异步线程中执行,执行结果返回Future public Future systemClientTest() { log.info("开始使用SystemClient..."); String s = systemFeignClient.test("1001"); return new AsyncResult<>(s); } } ``` ### 在Filter中使用 在其他Bean中使用是一样的哈。 ```java @Slf4j @Component public class TestFilter implements GlobalFilter, Ordered { @Autowired private ClientHolder clientHolder; @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { callClient(); return chain.filter(exchange); } private void callClient() { // 使用Client Future stringFuture = clientHolder.systemClientTest(); try { log.info("stringFuture.rs :{}", stringFuture.get()); } catch (Exception e) { e.printStackTrace(); } } @Override public int getOrder() { return Ordered.HIGHEST_PRECEDENCE; } } ``` ### 异步线程池配置 ```java @Configuration @EnableAsync(proxyTargetClass = true) public class AsycTaskConfig { @Bean public TaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // 我这里是固定写死的哦,实际不能这样写的哦 // 可以使用 Runtime.getRuntime().availableProcessors() 获取系统核心数进行配置 executor.setCorePoolSize(4); executor.setMaxPoolSize(8); executor.setQueueCapacity(1000); executor.setThreadNamePrefix("my-core-"); // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.initialize(); return executor; } } ``` ## 完整代码 [完整代码链接 码云地址](https://gitee.com/smilejj/springcloud-test) ## 写在最后 笔者刚开始写博客,若是帮助到您,帮忙点赞推荐下哦 ~