//下单,使用rebbion组件实现负载均衡。
@RequestMapping("/createOrder/{pid}")
public Order createOrder(@PathVariable Integer pid) {
//使用微服务的名字,从注册中心Nacos中获取
String url = "service-product2021";
Product product = restTemplate.getForObject("http://" + url + "/findProductById/" + pid, Product.class);
Order order = new Order();
order.setNumber(2);
order.setUid(1);
order.setUsername("chenchen");
order.setPid(product.getPid());
order.setPname(product.getPname());
order.setPprice(product.getPprice());
return orderService.createOrder(order);
}
上面接口看着是没有任何问题,都可以正常请求,但是有待完善的地方,如 :
Product product = restTemplate.getForObject(“http://” + url + “/findProductById/” + pid, Product.class);当前方法与同方法中的orderService.createOrder()显得格格不入,因为他是使用的模板方法resttemplate调用的远程服务,而createOrder(order)则为本地方法,说明代码风格不统一、且可读性查。所以需要我们改进,此时引入了一个组件Feign
一、Feign
1、啥时Feign?
说白了它就是spring官方提供的一个声明式伪HTTP客户端,它可以调用远程服务就像调用本地方法一样,只要在服务调用方提供一个接口然后添加注解就可以使用了。
2、使用步骤
2.1 在服务调用方shop-order的pom中添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.2 启动类上添加@EnableFeignClients注解
@EnableDiscoveryClient//开启nocas客户端服务
@EnableFeignClients//开启FeignClient客户端服务
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
System.out.println("订单微服务启动成功");
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
2.3 服务调用方创建接口,然后使用feign调用(此处方法需要和服务提供方Controller层一直,否则无法实现调用404)
package com.chenchen.service;
import com.chenchen.entity.Product;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@FeignClient(value = "service-product2021")
public interface IProductService {
@RequestMapping("/findProductById/{id}")
Product findProductById(@PathVariable("id") Integer id);
}
2.4、最后一步修改原有调用方法,直接调用
@Autowired
private IProductService productService;
//下单 使用feign调用远程服务
@RequestMapping("/createOrder/{pid}")
public Order createOrder(@PathVariable Integer pid) {
//使用微服务的名字,从注册中心Nacos中获取
//String url = "service-product2021";
Product product = productService.findProdutById(pid);
//Product product = restTemplate.getForObject("http://" + url + "/findProductById/" + pid, Product.class);
Order order = new Order();
order.setNumber(2);
order.setUid(1);
order.setUsername("chenchen");
order.setPid(product.getPid());
order.setPname(product.getPname());
order.setPprice(product.getPprice());
return orderService.createOrder(order);
}