两个微服务互相调用
两个微服务模块:goods微服务,orders微服务;orders服务调用goods服务。*通过spring cloud的feign组件进行,此次调用不依赖注册中心。至于feign组件以及注册中心不了解的请自行查阅。步骤一:创建一个maven工程1.1创建一个空项目1.2 删除src目录,并在pom.xml中添加所需依赖。pom.xml<?xml ver...
两个微服务模块:goods微服务,orders微服务;
orders服务调用goods服务。
*通过spring cloud的feign组件进行,此次调用不依赖注册中心。至于feign组件以及注册中心不了解的请自行查阅。
步骤一:创建一个maven工程
1.1创建一个空项目
1.2 删除src目录,并在pom.xml中添加所需依赖。
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.dyj.test</groupId>
<artifactId>springcloud-test</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<!-- 资源文件拷贝插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- java编译插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
1.3 创建goods微服务:右键springcloudtest项目-->new-->module-->maven-->next,此时目录结构如右图所示:
1.4 创建orders微服务:右键springcloudtest项目-->new-->module-->maven-->next,此时目录结构如右图所示:
说明:为什么goods服务有两个模块?
dyj-goods-api:微服务对外提供的REST API接口定义,以及接口中所用到的DTO类,供外部服务调用。
dyj-goods-web:微服务内部的具体实现
为什么orders服务只有一个模块?
orders服务其实也可以创建一个dyj-orders-api模块,但是在此次微服务调用例子中,orders服务调用goods服务,其本身并不需要对外部服务提供功能,故没有再创建dyj-orders-api模块。
步骤二:goods服务
2.1 dyj-goods-web模块的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springcloud-test</artifactId>
<groupId>com.dyj.test</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dyj-goods-web</artifactId>
<dependencies>
<dependency>
<groupId>com.dyj.test</groupId>
<artifactId>dyj-goods-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.3.1.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.3.1.Final</version>
</dependency>
</dependencies>
</project>
说明:dyj-goods-web模块依赖于dyj-goods-api,但两者属于一个服务
2.2 goods微服务模块:结构如下图
2.2.1 GoodsApi
package com.dyj.goods.api;
import com.dyj.goods.dto.GoodsDto;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@RequestMapping("/api/")
public interface GoodsApi {
@GetMapping("/getGoodsDto")
GoodsDto getGoodsDto(@RequestParam(value = "id") String id);
}
2.2.2 GoodsDto
package com.dyj.goods.dto;
public class GoodsDto {
private String id;
private String name;
private double advicePrice;
private String unit;//单位
public GoodsDto(){}
public GoodsDto(String id, String name, double advicePrice, String unit) {
this.id = id;
this.name = name;
this.advicePrice = advicePrice;
this.unit = unit;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getAdvicePrice() {
return advicePrice;
}
public void setAdvicePrice(double advicePrice) {
this.advicePrice = advicePrice;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
}
2.2.3 Goods
package com.dyj.goods.entity;
public class Goods {
private String id;
private String name;
private String ramark;//备注
private double costPrice;//成本价
private double advicePrice;//建议价
private int num;//存量
private String unit;//单位
public Goods(){}
public Goods(String id, String name, String ramark, double costPrice, double advicePrice, int num, String unit) {
this.id = id;
this.name = name;
this.ramark = ramark;
this.costPrice = costPrice;
this.advicePrice = advicePrice;
this.num = num;
this.unit = unit;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRamark() {
return ramark;
}
public void setRamark(String ramark) {
this.ramark = ramark;
}
public double getCostPrice() {
return costPrice;
}
public void setCostPrice(double costPrice) {
this.costPrice = costPrice;
}
public double getAdvicePrice() {
return advicePrice;
}
public void setAdvicePrice(double advicePrice) {
this.advicePrice = advicePrice;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
}
2.2.4 GoodsService(为节省时间,只为展示效果,并没有连接数据库,模拟实现)
package com.dyj.goods.service;
import com.dyj.goods.entity.Goods;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
public class GoodsService {
private static final Map<String, Goods> GOODS_MAP = new HashMap<>();
static {// 准备一些静态数据,模拟数据库
GOODS_MAP.put("1", new Goods("1","花生","备注花生",1,2.5,100,"袋"));
GOODS_MAP.put("2", new Goods("2","啤酒","备注啤酒",20,36,200,"箱"));
GOODS_MAP.put("3", new Goods("3","碳酸汽水","备注碳酸汽水",1.5,3,3000,"瓶"));
}
public Goods getGoodsById(String id){
Goods goods=new Goods();
for(Goods g:GOODS_MAP.values()){
if(id.equals(g.getId())){
goods=g;
}
}
return goods;
}
}
2.2.5 GoodsController
package com.dyj.goods.controller;
import com.dyj.goods.entity.Goods;
import com.dyj.goods.service.GoodsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value="/goods")
public class GoodsController {
@Autowired
private GoodsService goodsService;
/**
* 对外提供接口服务,查询商品信息
*
* @param id
* @return
*/
@GetMapping(value="/getGoodsById")
public Goods getGoodsById(@RequestParam(value="id") String id){
Goods goods= goodsService.getGoodsById(id);
return goods;
}
}
2.2.6 GoodsMapper
package com.dyj.goods.mapper;
import com.dyj.goods.dto.GoodsDto;
import com.dyj.goods.entity.Goods;
import org.mapstruct.Mapper;
@Mapper(componentModel="spring")
public abstract class GoodsMapper {
public abstract GoodsDto entityToDto(Goods entity);
/**
* 将数据传输对象转换为实体。
*
* @param dto 数据传输对象。
* @return 实体。
*/
public abstract Goods dtoToEntity(GoodsDto dto);
}
2.2.7 GoodsRest
package com.dyj.goods.rest;
import com.dyj.goods.api.GoodsApi;
import com.dyj.goods.dto.GoodsDto;
import com.dyj.goods.mapper.GoodsMapper;
import com.dyj.goods.service.GoodsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GoodsRest implements GoodsApi {
@Autowired
GoodsService goodsService;
@Autowired
GoodsMapper goodsMapper;
@Override
public GoodsDto getGoodsDto(@RequestParam(value = "id") String id){
GoodsDto g=goodsMapper.entityToDto(goodsService.getGoodsById(id));
return g;
}
}
2.2.8 GoodsApplication(启动类)
package com.dyj.goods;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = {"com.dyj.goods"})
public class GoodsApplication {
public static void main(String[] args) {
SpringApplication.run(GoodsApplication.class, args);
}
}
在dyj-goods-web模块下的resources目录下新建一个application.properties文件,内容如下:
server.port=8082
spring.application.name=dyj-goods
说明:GoodsMapper类是用来进行dto与entity互相转换的,GoodsRest是goods服务对外api接口的实现类
至此,goods服务结束,可以直接run GoodsApplication类,效果如下
步骤三:orders服务
3.1 dyj-orders-web模块的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springcloud-test</artifactId>
<groupId>com.dyj.test</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dyj-orders-web</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>com.dyj.test</groupId>
<artifactId>dyj-goods-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.3.1.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.3.1.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-ribbon -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
<version>2.0.3.RELEASE</version>
<exclusions>
<exclusion>
<artifactId>spring-cloud-starter</artifactId>
<groupId>org.springframework.cloud</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
说明:dyj-orders-web模块依赖于dyj-goods-api
3.2 orders微服务模块:结构如下图
3.2.1 GoodsClient (两个微服务通信的关键类)
package com.dyj.orders.client;
import com.dyj.goods.api.GoodsApi;
import org.springframework.cloud.openfeign.FeignClient;
@FeignClient(value = "dyj-goods" ,url = "localhost:8082")
public interface GoodsClient extends GoodsApi{
}
说明:@FeignClient注解 value值为依赖的微服务名字(该名字在goods服务的application.properties文件中指定)
3.2.2 Orders
package com.dyj.orders.entity;
import java.util.Date;
public class Orders {
private String id;
private Date date;//订单创建日期
private String address;
private String goodsId;
private int saleNum;//销售数量
public Orders() {
}
public Orders(String id, Date date, String address, String goodsId, int saleNum) {
this.id = id;
this.date = date;
this.address = address;
this.goodsId = goodsId;
this.saleNum = saleNum;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getGoodsId() {
return goodsId;
}
public void setGoodsId(String goodsId) {
this.goodsId = goodsId;
}
public int getSaleNum() {
return saleNum;
}
public void setSaleNum(int saleNum) {
this.saleNum = saleNum;
}
}
3.2.3 OrdersDto
package com.dyj.orders.service.dto;
import java.util.Date;
public class OrdersDto {
private String id;
private Date date;
private String address;
private int saleNum;
private String goodsId;
private String name;
private double advicePrice;
private String unit;//单位
public OrdersDto(){}
public OrdersDto(String id, Date date, String address, int saleNum, String goodsId, String name, double advicePrice, String unit) {
this.id = id;
this.date = date;
this.address = address;
this.saleNum = saleNum;
this.goodsId = goodsId;
this.name = name;
this.advicePrice = advicePrice;
this.unit = unit;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getSaleNum() {
return saleNum;
}
public void setSaleNum(int saleNum) {
this.saleNum = saleNum;
}
public String getGoodsId() {
return goodsId;
}
public void setGoodsId(String goodsId) {
this.goodsId = goodsId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getAdvicePrice() {
return advicePrice;
}
public void setAdvicePrice(double advicePrice) {
this.advicePrice = advicePrice;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
}
3.2.4 OrdersMapper
package com.dyj.orders.mapper;
import com.dyj.orders.entity.Orders;
import com.dyj.orders.service.dto.OrdersDto;
import org.mapstruct.Mapper;
@Mapper(componentModel="spring")
public abstract class OrdersMapper {
public abstract OrdersDto entityToDto(Orders entity);
/**
* 将数据传输对象转换为实体。
*
* @param dto 数据传输对象。
* @return 实体。
*/
public abstract Orders dtoToEntity(OrdersDto dto);
}
3.2.5 OrdersService
package com.dyj.orders.service;
import com.dyj.goods.api.GoodsApi;
import com.dyj.goods.dto.GoodsDto;
import com.dyj.orders.entity.Orders;
import com.dyj.orders.mapper.OrdersMapper;
import com.dyj.orders.service.dto.OrdersDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
@Service
public class OrderService {
private static final Map<String, Orders> ORDER_DATA = new HashMap<String, Orders>();
@Autowired
GoodsApi goodsApi;
@Autowired
OrdersMapper ordersMapper;
static {
// 模拟数据库
Orders orders = new Orders();
orders.setId("007");
orders.setDate(new Date());
orders.setAddress("北京市海淀区xx镇");
orders.setSaleNum(5);
orders.setGoodsId("2");
ORDER_DATA.put(orders.getId(), orders);
}
/**
* 根据订单id查询订单数据
*
* @param id
* @return
*/
public OrdersDto getOrderById(String id) {
Orders orders = ORDER_DATA.get(id);
if (null == orders) {
return null;
}
// 通过商品微服务查询商品详细数据
GoodsDto goodsDto = goodsApi.getGoodsDto(orders.getGoodsId());
OrdersDto ordersDto= ordersMapper.entityToDto(orders);
ordersDto.setName(goodsDto.getName());
ordersDto.setAdvicePrice(goodsDto.getAdvicePrice());
ordersDto.setUnit(goodsDto.getUnit());
return ordersDto;
}
}
3.2.6 OrdersController
package com.dyj.orders.controller;
import com.dyj.orders.service.OrderService;
import com.dyj.orders.service.dto.OrdersDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/orders")
public class OrderController {
@Autowired
OrderService orderService;
@GetMapping(value = "/id")
public OrdersDto getOrderById(@RequestParam(value = "id")String id) {
return this.orderService.getOrderById(id);
}
}
3.2.7 OrdersApplication(启动类)
package com.dyj.orders;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients
@SpringBootApplication(scanBasePackages = {"com.dyj.orders"})
public class OrdersApplication {
public static void main(String[] args){
SpringApplication.run(OrdersApplication.class,args);
}
}
在dyj-orderss-web模块下的resources目录下新建一个application.properties文件,内容如下:
server.port=8083
spring.application.name=dyj-orders
至此,orders服务调用goods服务结束,现在启动两个服务,可以看到,调用orders服务提供的getOrderById方法,orders服务会去调用goods服务,查询goodsId对应的数据,再返回给orders。测试效果效果如下
总结:像目录分层里面的controller、service、dto、mapper、api 、rest、client,只是为了便于规范利于后续开发,此篇最重要的就是client目录下的GoodsClient类了,这也是springcloud中feign组件的初体验。
好了,就这。。。
更多推荐
所有评论(0)