消费者订单模块
我们书接上文,看下图,我们上文已经创建了支付模块,现在该创建消费者订单模块,项目名称为:cloud-consumer-order80
创建工程
步骤和之前一样,不再赘述。
修改 pom 文件
<dependencies>
<!--引入自己定义发布的jar包 自己定义的jar通过maven的clean和install指令进行发布到本地仓库-->
<dependency>
<groupId>cn.com.dmg</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!--包含了sleuth+zipkin-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
修改 yml 文件
server:
port: 80 #因为用户用的时候一般不会关心端口号
spring:
application:
name: cloud-order-service #服务名称 在使用服务注册的时候使用
主启动类
package cn.com.dmg.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
//@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration = MySelfRule.class)
public class OrderMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderMain80.class,args);
}
}
业务类
客户端中不需要有 service 和 dao 层,只要有 controller 就行,因为客户端是调用生产者的,需要使用 restTemplate 调用,发送 http 请求。
什么是 restTemplate ?
RestTemplate 提供了多种便捷访问远程 Http 服务的方法,是一种简单便捷的访问 restful 服务模板类,是 Spring 提供的用于访问Rest 服务的客户端模板工具集。
如何使用?
使用 restTemplate 访问 restful 接口非常的简单粗暴无脑。
(url,requestMap,ResponseBeanclass) 这三个参数分别代表 REST请求地址、请求参数、HTTP 响应转换被转换成的对象类型。
下面我们就写一个 controller 类使用一下
使用 restTemplate 的时候,需要将他注入到 springboot 的容器当中,因此需要写一个配置类
package cn.com.dmg.springcloud.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* 这个类就相当于之前的spring项目中的applicationConteext.xml文件
* 而@Bean注解就相当于之前的
* <bean id="" class=""></bean>
*/
@Configuration
public class ApplicationContextConfig {
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
下面是 controller 类
import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
@RestController
@Slf4j
public class OrderController {
public static final String PAYMENT_URL = "http://localhost:8001";
@Resource
private RestTemplate restTemplate;
@GetMapping("/consumer/payment/create")
public CommonResult<Payment> create(Payment payment){
return restTemplate.postForObject(PAYMENT_URL+"/payment/create",payment,CommonResult.class); //写操作
}
@GetMapping("/consumer/payment/get/{id}")
public CommonResult<Payment> getPayment(@PathVariable("id") Long id){
return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);
}
}
代码已经开源,需要自取哦:
测试效果
- 先启动 cloud-provider-payment8001
- 再启动 cloud-consumer-order80
- 访问 http://localhost/consumer/payment/get/1
8001 项目不要忘记添加 @RequestBody 注解
工程重构
原因
在多个微服务项目中都会有相同的类,比如 entities 中的 Payment类,代码冗余。
1.新建 cloud-api-commons 工程
2.修改 pom 文件
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
<!--糊涂工具包-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.1.0</version>
</dependency>
</dependencies>
3.创建实体类
Payment
package cn.com.dmg.springcloud.entities;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@AllArgsConstructor //全参构造方法
@NoArgsConstructor //无参构造方法
public class Payment implements Serializable {//序列化在分布式部署的时候可能会用到
private long id;
private String serial;
}
CommonResult 返回结果时的公共类
package cn.com.dmg.springcloud.entities;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult<T> {
private Integer code;
private String message;
private T data;
public CommonResult(Integer code,String message){
this(code,message,null);
}
}
4.maven 命令 clean install
5.订单80和支付8001分别改造
删除各自的原先有过的entities文件夹
各自黏贴POM内容(下面是我的项目,groupId 和 artifactId 要改成你自己的)
<dependency>
<groupId>cn.com.dmg</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
6.将项目中原本的实体类删除,改为引用 common 服务的
7.重新启动进行测试
至此,消费者订单模块和工程重构已经完成。
文章中涉及的源代码已经开源: