假设有一个订单服务和一个商品服务,订单服务需要调用商品服务的某个接口。
商品服务接口如下
@RestController
public class ProductController {
@GetMapping("/msg")
public String msg(){
return "这里是商品信息";
}
}
接下来是订单服务如何调用商品服务的方法
一、RestTemplate
1. 直接使用RestTemplate
@RestController
@RequestMapping("/order")
public class OrderController {
@GetMapping("/getProductMsg")
public Object getProductMsg() {
RestTemplate restTemplate = new RestTemplate();
String response = restTemplate.getForObject("http://localhost:8082/msg",String.class);
return response;
}
}
2. 利用LoadBalancerClient通过应用名称获取URL,然后再使用RestTemplate,如果有多个商品应用,会采取负载均衡策略来选择不同主机
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private LoadBalancerClient loadBalancerClient;
@GetMapping("/getProductMsg")
public Object getProductMsg() {
// 利用LoadBalancerClient通过应用名称获取URL,然后再使用RestTemplate,如果有多个应用,会采取负载均衡策略来选择不同的应用
ServiceInstance serviceInstance = loadBalancerClient.choose("PRODUCT"); // 这里的PRODUCT是指商品服务的实例名称
String url = String.format("http://%s:%s",serviceInstance.getHost(), serviceInstance.getPort()) + "/msg";
System.out.println("请求地址:" + url);
RestTemplate restTemplate = new RestTemplate();
String response = restTemplate.getForObject(url,String.class);
return response;
}
}
3. 利用@LoadBalanced,可直接在RestTemplate使用应用名字来访问,如果有多个商品应用,会采取负载均衡策略来选择不同的主机。
新建一个RestTemplateConfig.java
@Component
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
服务调用
@RestController
public class OrderController {
// 方法3
@Autowired
private RestTemplate restTemplate;
@GetMapping("/getProductMsg")
public Object getProductMsg() {
// (利用@LoadBalanced,可直接在RestTemplate使用应用名字来访问),如果有多个应用,会采取负载均衡策略来选择不同的应用
String response = restTemplate.getForObject("http://PRODUCT/msg", String.class);
return response;
}
}
二、Feign
在订单服务的pom.xml添加相关依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
在启动类添加@EnableFeignClients注解
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
创建ProductClient接口,用于调用商品服务的接口
@FeignClient(name = "product") // name代表商品服务的实例名称
public interface ProductClient {
@GetMapping("/msg") // 这个路由一定要跟商品服务的路由保持一致,方法名可以任意填写
public String msg();
}
在Controller调用接口
@RestController
public class OrderController {
@Autowired
private ProductClient productClient;
@GetMapping("/getProductMsg")
public Object getProductMsg() {
String response = productClient.msg();
return response;
}
}
可以看出,我们当然是用feign更加方便啦。