1.引入依賴
<!--openFeign--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!--負載均衡器--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency>
2.啟用OpenFeign
在cart-service
的CartApplication
啟動類上添加注解,啟動OpenFeign功能
@EnableFeignClients
@MapperScan("com.hmall.cart.mapper")
@SpringBootApplication
public class CartApplication {public static void main(String[] args) {SpringApplication.run(CartApplication.class, args);}@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}
}
3.編寫OpenFeign客戶端
在cart-service
中,定義一個新的接口,編寫Feign客戶端
package com.hmall.cart.client;import com.hmall.cart.domain.dto.ItemDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;import java.util.List;@FeignClient("item-service")
public interface ItemClient {@GetMapping("/items")List<ItemDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids);
}
-
@FeignClient("item-service")
:聲明服務名稱 -
@GetMapping
:聲明請求方式 -
@GetMapping("/items")
:聲明請求路徑 -
@RequestParam("ids") Collection<Long> ids
:聲明請求參數 -
List<ItemDTO>
:返回值類型
有了上述信息,OpenFeign就可以利用動態代理幫我們實現這個方法,并且向http://item-service/items
發送一個GET
請求,攜帶ids為請求參數,并自動將返回值處理為List<ItemDTO>
。
我們只需要直接調用這個方法,即可實現遠程調用了。
4.使用FeignClient
在我們的service中實現微服務調用
// 1.獲取商品idSet<Long> itemIds = vos.stream().map(CartVO::getItemId).collect(Collectors.toSet());// 2.查詢商品// List<ItemDTO> items = itemService.queryItemByIds(itemIds);// 2.1 根據服務名稱獲取實例列表List<ServiceInstance> instances = discoveryClient.getInstances("item-service");if (CollUtils.isEmpty(instances)){return;}//2.2 手寫負載均衡,從實例列表中挑選一個實例ServiceInstance serviceInstance = instances.get(RandomUtil.randomInt(instances.size()));// 2.1.利用RestTemplate發起http請求,得到http的響應ResponseEntity<List<ItemDTO>> response = restTemplate.exchange(
// "http://localhost:8081/items?ids={ids}",serviceInstance.getUri() + "/items?ids={ids}",HttpMethod.GET,null,new ParameterizedTypeReference<List<ItemDTO>>() {},Map.of("ids", CollUtil.join(itemIds, ",")));// 2.2.解析響應if(!response.getStatusCode().is2xxSuccessful()){// 查詢失敗,直接結束return;}List<ItemDTO> items = response.getBody();
上面一大串上次寫的RestTemplate的代碼可以直接簡化為下面兩句了
// 1.獲取商品id
Set<Long> itemIds = vos.stream().map(CartVO::getItemId).collect(Collectors.toSet());
// 2.微服務調用
List<ItemDTO> items = itemClient.queryByIds(itemIds);
feign替我們完成了服務拉取、負載均衡、發送http請求的所有工作