一、SpringCloud 版本选择
SpringCloud:Hoxton.SR1 SpringBoot:2.2.2。RELEASE SpringCloudAlibaba:2.1.0.RELEASE Java:Java8 Maven:3.5 及以上 MySQL:5.7 及以上
二、微服务 cloud 整体聚合父工程 project
2.1 创建父工程步骤
1、New Project 2、聚合总父工程名字 3、选择 Maven 版本 4、修改字符编码 5、注解生效激活 7、Java 编译版本选择 8
2.2 父工程 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.atguigu.springcloud</groupId>
<artifactId>cloud2020</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>cloud-provide-payment8001</module>
<module>cloud-consumer-order80</module>
<module>cloud-api-commons</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<junit.version>4.12</junit.version>
<log4j.version>1.2.17</log4j.version>
<lombok.version>1.16.18</lombok.version>
<mysql.version>8.0.26</mysql.version>
<druid.version>1.1.16</druid.version>
<mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.spring.boot.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<optional>true</optional>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.2.2.RELEASE</version>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
</project>
Maven 中的 DependencyManagement 和 Dependencies: Maven 使用dependencyManagement 元素来提供了一种管理依赖版本号的方式。 通常会在一个组织或者项目的最顶层的父POM 中看到dependencyManagement 元素。 使用pom.xml 中的dependencyManagement 元素能让所有在子项目中引用一个依赖而不用显式的列出版本号。 Maven 会沿着父子层次向上走,直到找到一个拥有dependencyManagement 元素的项目,然后它就会使用这个 dependencyManagement 元素中指定的版本号。
这样做的好处就是:如果有多个子项目都引用同一样依赖,则可以避免在每个使用的子项目里都声明一个版本号,这样当想升级或切换到另一个版本时,只需要在顶层父容器里更新,而不需要一个一个子项目的修改 ;另外如果某个子项目需要另外的一个版本,只需要声明version就可。
- dependencyManagement里只是声明依赖, 并不实现引入 ,因此子项目需要显示的声明需要用的依赖。
- 如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom;
- 如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。
如果父工程的 pom.xml 文件中的 dependency 报红,可以暂时将 dependencyManagement 标签注释掉,报红原因就是因为 dependencyManagement 只是声明,并不会实际引入。
三、Rest 微服务工程构建
3.1 构建步骤
3.1.1 cloud-provider-payment8001 微服务提供者支付 Module 模块
1、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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.atguigu.springcloud</groupId>
<artifactId>cloud2020</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath/>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-provide-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>
<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>
<version>1.1.10</version>
</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.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>
2、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
url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: root
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.atguigu.springcloud.entities
3、主启动类
@SpringBootApplication
public class PaymentMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8001.class, args);
}
}
4、业务类 (1) 建表 SQL:
CREATE TABLE `payment` (
`id` bigint NOT NULL AUTO_INCREMENT,
`serial` varchar(200) DEFAULT NULL,
PRIMARY KEY (`id`)
);
(2)实体类 Payment
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Payment {
private Long id;
private String serial;
}
(3)JSON 封装类 CommonResult
@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)DAO 接口 PaymentMapper
package com.atguigu.springcloud.dao;
import com.atguigu.springcloud.entities.Payment;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface PaymentMapper {
public int create(Payment payment);
public Payment getPaymentById(@Param("id") Long id);
}
接口映射文件 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.atguigu.springcloud.dao.PaymentMapper">
<insert id="create" useGeneratedKeys="true" keyProperty="id">
insert into payment (serial) values (#{serial})
</insert>
<resultMap id="BaseResultMap" type="com.atguigu.springcloud.entities.Payment">
<id column="id" property="id" jdbcType="BIGINT"></id>
<result column="serial" property="serial" jdbcType="VARCHAR"></result>
</resultMap>
<select id="getPaymentById" resultMap="BaseResultMap">
select * from payment where id=#{id}
</select>
</mapper>
(5)Service 接口 PaymentService
package com.atguigu.springcloud.service;
import com.atguigu.springcloud.entities.Payment;
public interface PaymentService {
public int create(Payment payment);
public Payment getPaymentById(Long id);
}
PaymentService 接口实现类:
package com.atguigu.springcloud.service.impl;
import com.atguigu.springcloud.dao.PaymentMapper;
import com.atguigu.springcloud.entities.Payment;
import com.atguigu.springcloud.service.PaymentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class PaymentServiceImpl implements PaymentService {
@Autowired
private PaymentMapper paymentMapper;
@Override
public int create(Payment payment) {
return paymentMapper.create(payment);
}
@Override
public Payment getPaymentById(Long id) {
return paymentMapper.getPaymentById(id);
}
}
(6)PaymentController
package com.atguigu.springcloud.controller;
import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import com.atguigu.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@Slf4j
public class PaymentController {
@Autowired
private PaymentService paymentService;
@PostMapping("/payment/create")
public CommonResult create(@RequestBody Payment payment){
int result = paymentService.create(payment);
log.info("********插入结果:" + result);
if(result > 0){
return new CommonResult(200, "插入数据库成功", payment);
} else {
return new CommonResult(444, "插入数据库失败", null);
}
}
@GetMapping("/payment/get/{id}")
public CommonResult getPaymentById(@PathVariable("id") Long id){
Payment payment = paymentService.getPaymentById(id);
log.info("*******查询结果:" + payment);
if(payment != null){
return new CommonResult(200, "查询成功", payment);
} else {
return new CommonResult(444, "没有对应记录,查询ID:"+id, null);
}
}
}
3.1.2 cloud-consumer-order80 微服务消费者订单 Module 模块
1、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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.atguigu.springcloud</groupId>
<artifactId>cloud2020</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath/>
</parent>
<artifactId>cloud-consumer-order80</artifactId>
<name>cloud-consumer-order80</name>
<properties>
<java.version>1.8</java.version>
</properties>
<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>
</project>
2、application.yml
server:
port: 80
3、主启动类
package com.atguigu.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class OrderMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderMain80.class, args);
}
}
4、业务类
(1)实体类 Payment
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Payment {
private Long id;
private String serial;
}
(2)JSON 封装类 CommonResult
@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);
}
}
(3)Config 配置类
package com.atguigu.springcloud.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 restTemplate(){
return new RestTemplate();
}
}
RestTemplate 提供了多种便捷访问 HTTP 服务的方法,是一种简单便捷的访问 RESTful 服务的模板类,是 Spring 提供的用于访问 REST 服务的客户端模板工具集 。
具体介绍可以参考 官网地址
使用: 使用 restTemplate 访问 RESTful 接口非常的简单粗暴无脑。(url, requestMap, ResponseBean.class) 这三个参数分别代表 REST 请求地址、请求参数、HTTP 响应转换被转换成的对象类型。
RestTemplate 介绍 Spring 框架提供的 RestTemplate 类可用于在应用中调用 rest 服务,它简化了与 http 服务的通信方式,统一了 RESTful 的标准,封装了 http 链接,我们只需要传入 URL 及返回值类型即可。相较于之前常用的 HttpClient, RestTemplate 是一种更优雅的调用 RESTful 服务的方式。
在 Spring 应用程序中访问第三方 REST 服务与使用 Spring RestTemplate 类有关。RestTemplate 类的设计原则与许多其他 Spring 模板类(例如 JdbcTemplate、JmsTemplate)相同,为执行复杂任务提供了一种具有默认行为的简化方法。
RestTemplate 默认依赖 JDK 提供 http 连接的能力(HttpURLConnection),如果有需要的话也可以通过 setRequestFactory 方法替换为例如 Apache HttpComponents、Netty 或 OKHttp 等其它 HTTP library。
考虑到 RestTemplate 类是为调用 REST 服务而设计的,因此它的主要方法与 REST 的基础紧密相连就不足为奇了,后者是 HTTP 协议的方法:HEAD、GET、POST、DELETE 和 OPTIONS。例如,RestTemplate 类具有 headForHeaders()、getForObject()、postForObject()、put() 和 delete() 等方法。
RestTemplate 方法介绍 该模板类的主要切入点为以下几个方法(并对应着 HTTP 的六个主要方法):
HTTP method | RestTemplate methods |
---|
GET | getForObject(String, Class<T>, Object...) | getForEntity(String, Class<T>, Object...) | POST | postForLocation(String, Object, Object...) | postForObject(String, Object, Class<T>, Object...) | PUT | put(String, Object, Object...) | DELETE | delete(String, Object...) | HEAD | headForHeaders(String, Object...) | OPTIONS | optionsForAllow(String, Object...) | any | exchanges(String, HttpMethod, HttpEntity<?>, Class<T>, Object...) | execute(String, HttpMethod, RequestCallback, ResponseExtraactor<T>, Object...) |
(4)Controller
package com.atguigu.springcloud.controller;
import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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;
@RestController
@Slf4j
public class OrderController {
public static final String PAYMENT_URL = "http://localhost:8001";
@Autowired
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 两个微服务中均有 Payment 实体类和 CommonResult 通用封装类。
新建 cloud-api-commons 服务,修改 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.atguigu.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
<name>cloud-api-commons</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.1.0</version>
</dependency>
</dependencies>
</project>
创建实体类 Payment 和通用封装类 CommonResult
(1)实体类 Payment
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Payment {
private Long id;
private String serial;
}
(2)JSON 封装类 CommonResult
@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);
}
}
至此,该服务创建完成,创建完成后,依次执行 maven 命令:clean 和 install 通过 install 命令,将 cloud-api-commons 服务打成 jar,并安装到本地 maven 仓库。
修改订单80 和支付 8001 两个服务: 删除各自的原先有过的 entities 文件夹,在各自的 pom.xml 文件中添加如下内容:
<dependency>
<groupId>com.atguigu.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
修改完成后,重启测试
|