前言:在上节我们新建了一个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-service
datasource:
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: root
password: 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 {
@Resource
private PaymentDao paymentDao;
@Override
public int insert(Payment payment) {
return paymentDao.insert(payment);
}
@Override
public 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 {
@Resource
private 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服务的客户端模板工具集
*/
@Bean
public 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";
@Resource
private 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 {
@Resource
private 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来进行服务间的调用