支付模块(服务生产者) 准备工作 创建一个 Module,一个空的 Maven 项目。并导入下面的依赖。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-web</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-actuator</artifactId > </dependency > <dependency > <groupId > org.mybatis.spring.boot</groupId > <artifactId > mybatis-spring-boot-starter</artifactId > </dependency > <dependency > <groupId > com.alibaba</groupId > <artifactId > druid-spring-boot-starter</artifactId > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-jdbc</artifactId > </dependency > <dependency > <groupId > org.projectlombok</groupId > <artifactId > lombok</artifactId > <optional > true</optional > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-test</artifactId > <scope > test</scope > </dependency > </dependencies >
在 resources 文件夹下创建 application.yaml 配置文件,并加入下面的配置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 server: port: 8001 spring: application: name: payment datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/springcloud?useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: root mybatis: mapperLocations: classpath:mapper/*.xml type-aliases-package: ml.guest997.pojo
创建主启动类。
1 2 3 4 5 6 7 8 9 10 11 package ml.guest997;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication public class Payment { public static void main (String[] args) { SpringApplication.run(Payment.class, args); } }
运行下面的 sql 语句创建数据库和表。
1 2 3 4 5 6 7 CREATE DATABASE `springcloud` ;USE `springcloud`; CREATE TABLE `payment` ( `id` bigint(20 ) NOT NULL AUTO_INCREMENT COMMENT 'ID' , `serial` varchar(200 ) DEFAULT '' , PRIMARY KEY (id) )ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4
POJO 层 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package ml.guest997.pojo;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import java.io.Serializable;@Data @AllArgsConstructor @NoArgsConstructor public class Payment implements Serializable { private static final long serialVersionUID = -3231455795280061701L ; private Long id; private String serial; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package ml.guest997.pojo;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 = code; this .message = message; this .data = null ; } }
Dao 层 1 2 3 4 5 6 7 8 9 10 11 12 package ml.guest997.dao;import ml.guest997.pojo.Payment;import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.annotations.Param;@Mapper public interface PaymentDao { int add (Payment payment) ; Payment getPaymentById (@Param("id") Long id) ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace ="ml.guest997.dao.PaymentDao" > <insert id ="add" parameterType ="Payment" useGeneratedKeys ="true" keyProperty ="id" > insert into payment(serial) values (# {serial} ); </insert > <resultMap id ="BaseResultMap" type ="Payment" > <id column ="id" property ="id" jdbcType ="BIGINT" /> <id column ="serial" property ="serial" jdbcType ="VARCHAR" /> </resultMap > <select id ="getPaymentById" parameterType ="Long" resultMap ="BaseResultMap" > select * from payment where id = # {id} ; </select > </mapper >
Service 层 1 2 3 4 5 6 7 8 9 10 package ml .guest997 .service ;import ml .guest997 .pojo .Payment ;import org .apache .ibatis .annotations .Param ;public interface PaymentService { int add (Payment payment); Payment getPaymentById (@Param ("id" ) Long id); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package ml.guest997.service.impl;import ml.guest997.dao.PaymentDao;import ml.guest997.pojo.Payment;import ml.guest997.service.PaymentService;import org.springframework.stereotype.Service;import javax.annotation.Resource;@Service public class PaymentServiceImpl implements PaymentService { @Resource private PaymentDao paymentDao; @Override public int add (Payment payment) { return paymentDao.add (payment) ; } @Override public Payment getPaymentById (Long id) { return paymentDao.getPaymentById (id) ; } }
Controller 层 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package ml.guest997.controller;import lombok.extern.slf4j.Slf4j;import ml.guest997.pojo.CommonResult;import ml.guest997.pojo.Payment;import ml.guest997.service.PaymentService;import org.springframework.web.bind.annotation .*;import javax.annotation .Resource;@RestController @Slf4j public class PaymentController { @Resource private PaymentService paymentService; @PostMapping("/payment/add" ) public CommonResult add(@RequestBody Payment payment) { int res = paymentService.add(payment); log.info("插入结果:" + res); if (res > 0 ) { return new CommonResult(200 , "插入数据库成功" , res); } else { return new CommonResult(400 , "插入数据库失败" ); } } @GetMapping(value = "/payment/get/{id}" ) public CommonResult<Payment> getPaymentById(@PathVariable("id" ) Long id) { Payment payment = paymentService.getPaymentById(id); if (payment != null ) { return new CommonResult(200 , "查询成功" , payment); } else { return new CommonResult(404 , "没有对应记录,查询 id 为:" + id); } } }
测试 启动模块后,使用 Postman 发送请求,(因为浏览器不能够通过 url 直接发送 Post 请求)分别是 Post 请求:127.0.0.1:8001/payment/add?serial=Guest001 和 Get 请求: 127.0.0.1:8001/payment/get/1,能够正常返回数据即可。
热部署(开发时使用,生产环境必须关闭) 导入下面的依赖。
1 2 3 4 5 6 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-devtools</artifactId > <scope > runtime</scope > <optional > true</optional > </dependency >
开启自动构建。
然后修改一下代码,看下控制台是否能自动构建即可。
订单模块(服务消费者) 准备工作 创建一个 Module,一个空的 Maven 项目。并导入下面的依赖。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-web</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-actuator</artifactId > </dependency > <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 > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-test</artifactId > <scope > test</scope > </dependency > </dependencies >
在 resources 文件夹下创建 application.yaml 配置文件,并加入下面的配置。
1 2 3 4 5 6 server: port: 80 spring: application: name: order
创建主启动类。
1 2 3 4 5 6 7 8 9 10 11 package ml.guest997;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication public class Order { public static void main (String[] args) { SpringApplication.run(Order.class, args); } }
POJO 层 就是上面的支付模块的代码,就不再赘述了。
Config 层 1 2 3 4 5 6 7 8 9 10 11 12 13 package ml.guest997.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.client.RestTemplate;@Configuration public class ApplicationContextConfig { @Bean public RestTemplate getRestTemplate () { return new RestTemplate(); } }
Controller 层 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package ml.guest997.controller;import ml.guest997.pojo.CommonResult;import ml.guest997.pojo.Payment;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 public class OrderController { public static final String PAYMENT_URL = "http://localhost:8001" ; @Resource private RestTemplate restTemplate; @GetMapping("/consumer/payment/add" ) public CommonResult add(Payment payment) { return restTemplate.postForObject(PAYMENT_URL + "/payment/add" , 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 ); } }
RestTemplate 提供了多种便捷访问远程 http 服务的方法,是一种简单便捷的访问 restful 服务模板类,是 Spring 提供的用于访问 Rest 服务的客户端模板工具集。
测试 将两个模块都启动后,浏览器访问地址:127.0.0.1//consumer/payment/add?serial=Guest002 和 127.0.0.1//consumer/payment/get/2,能够正常返回数据即可。
IDEA 开启 Services 为了方便管理多个微服务,可以通过 IDEA 开启 Services 进行统一管理。
工程重构 从上面的两个模块就能看出来,POJO 层的代码是冗余的,可能以后每写一个模块,就需要把这些代码都复制一份,十分的麻烦。我们可以通过新建个 Commons 模块,将这些冗余的代码放进去,在需要的模块下引入这个模块就能实现简单的复用了。
准备工作 创建一个 Module,一个空的 Maven 项目。并导入下面的依赖。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <dependencies > <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 > <dependency > <groupId > cn.hutool</groupId > <artifactId > hutool-all</artifactId > <version > 5.7.22</version > </dependency > </dependencies >
POJO 层 就是上面两个模块中冗余的 POJO 层代码。然后将另两个模块的 POJO 层删除。
编译打包 通过 IDEA 右侧栏中的 Maven 工具栏,将 Commons 模块编译打包以供其它模块使用。(先 clean 后 install)
引入依赖 在其它模块的 pom 配置文件中引入下面的依赖。
1 2 3 4 5 <dependency > <groupId > ml.guest997</groupId > <artifactId > Commons</artifactId > <version > $ {project.version} </version > </dependency >
测试 将两个模块都启动后,通过浏览器访问地址:127.0.0.1//consumer/payment/add?serial=Guest003 和 127.0.0.1//consumer/payment/get/3,能够正常返回数据即可。