前言:在上节我们新建了一个SpringCloud父工程,这一节主要是构建微服务工程,通过实现订单模块和支付模块来熟悉微服务的概念和构建过程。
1、在父工程下新建模块
2、选择模块的项目类型为Maven并选择模块要使用的JDK版本
3、填写子模块的名称,然后点完成即可完成创建
4、进入父工程的pom.xml文件里查看变化,可以发现多出了一个modules,这表明provider-payment8081这个模块成为了父工程spring-cloud01的子模块了
5、修改provider-payment8001子模块的pom.xml文件,然后reolad一下,下载依赖
例:
<?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>springcloud01</artifactId><groupId>com.ken.springcloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>provider-payment8001</artifactId><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><!--Mybatis和SpringBoot的整合--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId></dependency><!--mysql-connector-java--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--jdbc--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</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></project>
子模块里的依赖都没写版本号,没写版本号的情况下会继承父项目的版本
例:
父项目的mybatis版本为2.2.0
子模块的mybatis版本没有写,这时候子模块的版本为2.2.0,继承了父项目mybatis的版本
6、为子模块添加名为application的yml配置文件(注:yml是官方推荐的配置文件格式,最好使用yml文件而不是properties文件)
效果图:
如果application.yml不是绿色的,而是红色的,可以尝试install当前Maven工程,如果还不行可以尝试清除Idea的缓存
7、编写application.yml文件配置
#服务端口号
server:port: 8001#服务名称
spring:application:name: cloud-payment-servicedatasource:type: com.alibaba.druid.pool.DruidDataSource #当前数据源操作类型driver-class-name: com.mysql.cj.jdbc.Driver #mysql驱动包(我本地的mysql版本是8,版本是5的要写成com.mysql.jdbc.Driver)url: jdbc:mysql://localhost:3306/cloud?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8 #mysql连接路径,记得把cloud这个数据库名改成自己的,或者新建名为cloud的数据库username: rootpassword: 123456#mybatis配置
mybatis:mapper-locations: classpath:mapper/*.xml #扫描类路径下的mapper文件夹下所有的.xml配置文件type-aliases-package: com.ken.springcloud.entities #该包下的所有Entity类都取默认别名
效果图:
8、为子模块新建一个主启动类,类名输入com.ken.springcloud.PaymentMain,然后创建即可
效果图:
9、编写主启动类
package com.ken.springcloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class PaymentMain {public static void main(String[] args) {SpringApplication.run(PaymentMain.class, args);}
}
效果图:
10、新建数据库和表
数据库名为cloud,字符集为utf8mb4,排序规则为utf8mb4_general_ci,表名为payment
CREATE TABLE `payment` (`id` bigint NOT NULL AUTO_INCREMENT,`serial` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;
11、新建包entities和实体类Payment,在类名输入entities.Payment,然后创建即可
效果图:
12、编写Payment实体类的内容
package com.ken.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;}
13、新建返回给前端的结果集CommonResult类
效果图:
14、编写CommonResult实体类的内容
package com.ken.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);}}
15、新建包dao和接口类PaymentDao,在类名输入dao.PaymentDao,然后创建即可
效果图:
16、编写PaymentDao接口类的内容
package com.ken.springcloud.dao;import com.ken.springcloud.entities.Payment;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;@Mapper
public interface PaymentDao {int insert(Payment payment);Payment getPaymentById(@Param("id") Long id);}
17、在resources目录下新建mapper目录,用于存储mapper文件
效果图:
18、在mapper目录下新建PaymentMapper.xml文件
效果图:
19、编写PaymentMapper.xml的内容
<?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="com.ken.springcloud.dao.PaymentDao"><resultMap id="BaseResultMap" type="com.ken.springcloud.entities.Payment"><id column="id" property="id" jdbcType="BIGINT"/><id column="serial" property="serial" jdbcType="VARCHAR"/></resultMap><!--useGeneratedKeys设置为true时,表示如果插入的表id以自增列为主键,则允许JDBC支持自动生成主键,并可将自动生成的主键id返回。--><insert id="insert" parameterType="Payment" useGeneratedKeys="true" keyProperty="id">insert into payment(serial) values (#{serial});</insert><select id="getPaymentById" parameterType="Long" resultMap="BaseResultMap">select * from payment where id = #{id};</select></mapper>
20、新建包service和接口类PaymentService,在类名输入service.PaymentService,然后创建即可
效果图:
21、编写PaymentService接口类的内容
package com.ken.springcloud.service;import com.ken.springcloud.entities.Payment;
import org.apache.ibatis.annotations.Param;public interface PaymentService {int insert(Payment payment);Payment getPaymentById(@Param("id") Long id);}
22、在service包下新建impl包和接口实现类PaymentServiceImpl,在类名输入impl.PaymentServiceImpl,然后创建即可
效果图:
23、编写PaymentServiceImpl实现类的内容
package com.ken.springcloud.service.impl;import com.ken.springcloud.dao.PaymentDao;
import com.ken.springcloud.entities.Payment;
import com.ken.springcloud.service.PaymentService;
import org.springframework.stereotype.Service;import javax.annotation.Resource;@Service
public class PaymentServiceImpl implements PaymentService {@Resourceprivate PaymentDao paymentDao;@Overridepublic int insert(Payment payment) {return paymentDao.insert(payment);}@Overridepublic Payment getPaymentById(Long id) {return paymentDao.getPaymentById(id);}}
24、在com.ken.springcloud包下新建controller包和控制类,在类名输入controller.PaymentController,然后创建即可
效果图:
25、编写PaymentController控制类的内容
package com.ken.springcloud.controller;import com.ken.springcloud.entities.CommonResult;
import com.ken.springcloud.entities.Payment;
import com.ken.springcloud.service.PaymentService;
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.PostMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@RestController
@Slf4j
public class PaymentController {@Resourceprivate PaymentService paymentService;@PostMapping("/payment/insert")public CommonResult insert(Payment payment) {int result = paymentService.insert(payment);log.info("插入结果{}",result);if(result > 0) {return new CommonResult(200,"插入数据库成功",result);}else {return new CommonResult(500,"插入数据库失败",result);}}@GetMapping("/payment/get/{id}")public CommonResult insert(@PathVariable("id") Long id) {Payment payment = paymentService.getPaymentById(id);log.info("查询结果{}",payment);if(payment != null) {return new CommonResult(200,"查询成功",payment);}else {return new CommonResult(500,"没有对应的数据,查询失败,查询id" + id,payment);}}}
26、运行项目并用工具测试接口,查看项目是否运行成功(我这里测试接口用的工具的postman)
(1)测试新增
在地址栏输入http://localhost:8001/payment/insert?serial=ken并点击send调用接口,可以看到数据插入成功
效果图:
(2)测试查询
在地址栏输入http://localhost:8001/payment/get/1并点击send调用接口,可以看到数据返回成功
效果图:
27、在父工程下再次新建模块
28、选择新模块的项目类型为Maven并选择模块要使用的JDK版本
29、填写子模块的名称,然后点完成即可完成创建
效果图:
30、修改consumer-order80子模块的pom.xml文件,然后reolad一下,下载依赖
例:
<?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>springcloud01</artifactId><groupId>com.ken.springcloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>consumer-order80</artifactId><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><!--lombok插件--><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></project>
31、为子模块添加名为application的yml配置文件(注:yml是官方推荐的配置文件格式,最好使用yml文件而不是properties文件)
效果图:
如果application.yml不是绿色的,而是红色的,可以尝试install当前Maven工程,如果还不行可以尝试清除Idea的缓存
32、编写application.yml文件配置
server:port: 80 #用80端口是因为浏览器网页服务默认的端口号都是80(80端口是为HTTP开放的)
效果图:
33、为子模块新建一个主启动类,类名输入com.ken.springcloud.OrderMain,然后创建即可
效果图:
34、编写主启动类
package com.ken.springcloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class OrderMain {public static void main(String[] args) {SpringApplication.run(OrderMain.class,args);}}
效果图:
35、新建包entities和实体类Payment,在类名输入entities.Payment,然后创建即可
效果图:
36、在com.ken.springcloud包下新建config包和ApplicationContextConfig类,在类名输入config.ApplicationContextConfig,然后创建即可
效果图:
37、编写ApplicationContextConfig类
package com.ken.springcloud.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;@Configuration
public class ApplicationContextConfig {/*** RestTemplate提供了多种便捷访问远程Http服务的方法,是一种简单便捷的访问restful服务模板类,是Spring提供的用于访问Rest服务的客户端模板工具集*/@Beanpublic RestTemplate getRestTemplate() {return new RestTemplate();}}
38、在com.ken.springcloud包下新建controller包和控制类,在类名输入controller.OrderController,然后创建即可
效果图:
39、编写OrderController控制类的内容
package com.ken.springcloud.controller;import com.ken.springcloud.entities.CommonResult;
import com.ken.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.PostMapping;
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";@Resourceprivate RestTemplate restTemplate;@PostMapping("/consumer/insert")public CommonResult<Payment> insert(Payment payment) {return restTemplate.postForObject(PAYMENT_URL + "/payment/insert",payment,CommonResult.class);}@GetMapping("/consumer/get/{id}")public CommonResult<Payment> getPayment(@PathVariable("id") Long id) {return restTemplate.getForObject(PAYMENT_URL + "/payment/get" + id,CommonResult.class);}}
40、修改PaymenController控制类的内容(在insert方法的参数前多加了@RequestBody,之前测试时是没有加的,没有加的情况下用RestTemplate调用PaymenController类的insert接口,insert接口的入参的值都为null)
package com.ken.springcloud.controller;import com.ken.springcloud.entities.CommonResult;
import com.ken.springcloud.entities.Payment;
import com.ken.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;@RestController
@Slf4j
public class PaymentController {@Resourceprivate PaymentService paymentService;@PostMapping("/payment/insert")public CommonResult insert(@RequestBody Payment payment) {int result = paymentService.insert(payment);log.info("插入结果{}",result);if(result > 0) {return new CommonResult(200,"插入数据库成功",result);}else {return new CommonResult(500,"插入数据库失败",result);}}@GetMapping("/payment/get/{id}")public CommonResult insert(@PathVariable("id") Long id) {Payment payment = paymentService.getPaymentById(id);log.info("查询结果{}",payment);if(payment != null) {return new CommonResult(200,"查询成功",payment);}else {return new CommonResult(500,"没有对应的数据,查询失败,查询id" + id,payment);}}}
41、分别启动OrderMain启动类和PaymentMain启动类,然后用工具测试接口(我这里测试接口用的工具的postman)
(1)启动项目
(2)测试新增
在地址栏输入http://localhost:80/consumer/insert?serial=ken2并点击send调用接口,可以看到数据插入成功
效果图:
(3)测试查询
在地址栏输入http://localhost:80/consumer/get/2并点击send调用接口,可以看到数据返回成功
效果图:
结语:
至此,我们完成了微服务工程的构建并使用RestTemplate来进行服务间的调用