壹
继续第(六)篇RestTemplate篇
做到现在,本机上已经有注册中心: eureka, 服务:client、order、product
继续在order中实现通信向product服务,使用Feign方式
下面记录学习和遇到的问题
贰
order服务中, 开始需要在maven引入Feign的依赖,
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> <version>1.4.4.RELEASE</version> </dependency>
注意 : 此处是遇到了这个问题 , 必须加上版本version , 不然jar引入不全 , 导致使用不了相关API,比如@EnableFeignClients注解不存在的问题,如果想尝试一下了解依赖问题的话,(这边是windows系统)可以CMD进入项目文件路径,比如本机项目的目录是E:/MyCloud/order , 然后执行mvn clean install -U命令,他会告诉你依赖问题,比如缺少版本号等等,
要是不知道某些依赖的全称或版本, 推荐上maven仓库查找,附上URL: http://mvnrepository.com/
还有feign改过名字,改成了openfeign,可以用以下代替依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
下面先在启动类上加上一个fegin的注解@EnableFeignClients ,如下
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } }
接着请求目标服务product,相当于order是client,所以建一个ProductClient接口来完成任务
product服务
请求的接口还是上篇product中的简单接口,贴出来
@RestController public class ProductsController { @GetMapping("/products") public String products(){ return "hello,this is products"; } }
order服务中
接口ProductClient
@FeignClient("product")
public interface ProductClient {
@GetMapping("/products")
String getProduct();
}
以上@FeignClient(value="product"),product是注册中心product服务的Application名字,意思是这个client是访问product服务用的
Controller 使用该接口方式,比较方便,IDEA的@Autowired会爆红,不需要管他,没问题
@RestController
public class OrderController {
@Autowired
private ProductClient client;
@GetMapping("/get")
public String getProducts() {
String str = client.getProduct();
return str;
}
}
以上就简单的实现了Feign通信
Feign: 声明式rest客户端 ,以上的操作没有动product服务中的代码,只在order服务中操作, 以接口加注解的方式实现
再贴一个例子 在order服务中依据product的id集合获取product列表: ↓↓↓
product服务
Controller层代码:
@RestController
@RequestMapping("/product")
public class ProductController {
@Autowired
private ProductService productService;
@PostMapping("/orderList")
public List<Product> orderList(@RequestBody List<String> productIdList){
return productService.findByProductIdIn(productIdList);
}
}
Service 接口:
public interface ProductService {
List<Product> findByProductIdIn(List<String> productIdList);
}
Service 接口 实现:
@Service
public class ProductServiceImpl implements ProductService {
@Autowired
private ProductRepository repository;
@Override
public List<Product> findByProductIdIn(List<String> productIdList) {
return repository.findByProductIdIn(productIdList);
}
}
repository 接口 (JPA):
public interface ProductRepository extends JpaRepository<Product,String> {
List<Product> findByProductIdIn(List<String> productIdList);
}
product 对象:
@Entity
@Data
public class Product {
@Id
private String productId;
private String productName;
private BigDecimal productPrice;
private String productPicture;
}
@FeignClient 接口块
@FeignClient("product") public interface ProductClient { @PostMapping("/product/orderList") List<Product> getOrderList(@RequestBody List<String> productIdList); }
order服务
Controller测试 :
@RestController
public class OrderController {
@Autowired
private ProductClient client;
@GetMapping("/get")
public String getProductList() {
List<String> productIdList=Arrays.asList("1","2");
List<Product> productList = productClient.getOrderList(productIdList);
return "123";
}
}
两服务传递list类型参数的时候,需要Post请求,且@RequestBody注解转化
两边都设置了product对象,传与接
叁
操作是比较简单的,只是一个普通的访问,但是呢,还是存在一些low的操作
现在此处有order,product两个服务,比如一个下订单的操作的时候,返回类型和传参是个什么方式呢,自然的微服务下不是你一个人开发的,此处两个服务是举例,假设两个接口不是一个组的开发,也可能是对外部使用的接口,我们自己封装了一个返回类型和传参,那么别人也要跟着创建一个类型DTO什么的,比较不合适,而且容易传递无用,不安全的信息给别人,还有像之前每个服务都引入maven依赖,比如lombok,web什么的重复了
分享学习项目多模块,可以减少maven多余的依赖,也可以分层实现服务,还是比较容易入手的
-----------------------------------------------------------