什么是Rest
REST是Representational State Transfer的缩写,它是由罗伊·菲尔丁(Roy Fielding)提出的,是用来描述创建HTTP API的标准方法的,他发现这四种常用的行为(查看(view),创建(create),编辑(edit)和删除(delete))都可以直接映射到HTTP 中已实现的GET,POST,PUT和DELETE方法。
在实际应用上就是在controller层根据访问不同业务,去指定请求类型,如常用的post,get
什么是Api
全称Application Programming Interface(应用程序j接口)
什么是Rest Api
基于上述两个知识点就很好理解了,就是一个http的远程调用解决方案,它提供restTemplate等接口
目的:在微服务架构中的作用是让各微服务之间产生联系,方便调用
本质:基于http的具备restful风格的远程调用的接口,
什么是远程调用:建议看我的dubbo原理篇博客!!!
下面开始去做一个基于rest api的微服务架构
Rest学习环境搭建与测试
建一个maven(不要模板)项目,作为父项目
目的:将所有子项目的依赖到导入父项目中,控制各依赖项目的版本,解决了分布式项目中依赖版本不兼容问题
导入相关依赖

<?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.king</groupId> <artifactId>SpringCloudLearns</artifactId> <version>1.0-SNAPSHOT</version> <modules> <module>springcloud-api</module> <module>springcloud-provider-dept-8001</module> <module>springcloud-consumer-dept-80</module> </modules> <!--打包方式pom,默认的是jar--> <packaging>pom</packaging> <!--配置--> <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> <!-- <lombok.version>1.8.10</lombok.version>--> <log4j.version>1.2.17</log4j.version> </properties> <dependencyManagement> <dependencies> <!--springCloud的依赖--> <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.SR3</version> <type>pom</type> <scope>import</scope> </dependency> <!--springboot--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.4.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> <!--数据库--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.15</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.3</version> </dependency> <!--SpringBoot启动器--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <!--日志测试--> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.16</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> </dependency> </dependencies> </dependencyManagement> </project>
建立各业务模块
每个模块都是独立的一个微服务,通过改port,让他们能在一个tomcat中独立运行
涉及到的模块:
1.api(关注pojo)
导入相关依赖

<?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>SpringCloudLearns</artifactId> <groupId>com.king</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>springcloud-api</artifactId> <!--导入的是父类的已有的依赖,用的是<dependencyManagement>所以要自己导--> <!--微服务架构中尽量在父项目中导依赖,为了版本一致--> <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> </project>
实体类
//所有分布式架构的实体类都要先序列化 @Data @NoArgsConstructor @Accessors(chain = true) //链式写法 /*链式编程例子 * Dept dept = new Dept * dept.setdname('11').setdeptno(1); * */ public class Dept implements Serializable { private Long deptno; private String dname; //记录数据库来源,一个服务对应一个数据库 private String db_source; //第一个主键自增,第三个数据库函数,数据库自动获取,自动生成 public Dept(String dme) { this.dname = dname; } }
2.服务端(关注点:业务~model)
相关依赖

<?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>SpringCloudLearns</artifactId> <groupId>com.king</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>springcloud-provider-dept-8001</artifactId> <dependencies> <!--需要拿到实体类,所以需要配置api module--> <dependency> <groupId>com.king</groupId> <artifactId>springcloud-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <!--test--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--jetty--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jetty</artifactId> </dependency> <!--热部署工具--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> </dependencies> </project>
yaml 配置(数据库,mybatis,port配置)
server: port: 8001 #mybatis配置 mybatis: mapper-locations: classpath*:mybatis/mapper/*.xml type-aliases-package: com.king.springcloud.pojo #spring配置 spring: application: name: springcloud-provider-dept datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/springcloudlearns?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8 username: root password: 123456
mapper

@Mapper @Repository public interface DeptMapper { boolean addDept(Dept dept); Dept queryById(@Param("deptno") Long id); List<Dept> queryAll(); }
mapper.xml

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.king.springcloud.mapper.DeptMapper"> <insert id="addDept" parameterType="Dept"> insert into dept (dname,db_source) values (#{dname},database()) </insert> <select id="queryById" parameterType="Long" resultType="Dept"> select * from dept where deptno=#{deptno}; </select> <select id="queryAll" resultType="Dept"> select * from dept; </select> </mapper>
service接口

public interface DeptService { boolean addDept(Dept dept); Dept queryById(Long id); List<Dept> queryAll(); }
serviceImpl

@Service public class DeptServiceImpl implements DeptService{ @Autowired private DeptMapper deptMapper; @Override public boolean addDept(Dept dept) { return deptMapper.addDept(dept); } @Override public Dept queryById(Long id) { return deptMapper.queryById(id); } @Override public List<Dept> queryAll() { return deptMapper.queryAll(); } }
创建主启动类

@SpringBootApplication public class DeptProvider_8001 { public static void main(String[] args) { SpringApplication.run(DeptProvider_8001.class,args); } }
3.客户端(关注点:view~controller)重要
maven依赖

<?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>SpringCloudLearns</artifactId> <groupId>com.king</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>springcloud-consumer-dept-80</artifactId> <!--实体类+web--> <dependencies> <dependency> <groupId>com.king</groupId> <artifactId>springcloud-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> </dependencies> </project>
配置端口号:80()客户端一般都是80
RestTemplate不是spring的组件所以要去配置(@Bean)

//@Configuration,相当于spring中的applicationContext.xml @Configuration public class ConfigBean { @Bean public RestTemplate getRestTemplate(){ return new RestTemplate(); } }
controller
@RestController public class DeptConsumerController { //理解:消费者不应该又service层~,那么怎么去调用其他服务器端的服务呢? //解决:远程调用,RestTemplate基于http的远程调用接口服务,注册到spring中 //(url,实体:Map,class<T>responseType) @Autowired private RestTemplate restTemplate; private static final String REST_URL_PREFIX = "http://localhost:8001"; @RequestMapping("/consumer/dept/add/{dname}") public Boolean add(@PathVariable("dname") String dname){ System.out.println(dname); Dept dept = new Dept(); dept.setDname(dname); return restTemplate.postForObject(REST_URL_PREFIX+"dept/add",dept,Boolean.class); } //http://localhost:8001/dept/get/{id} @RequestMapping("/consumer/dept/get/{id}") public Dept get(@PathVariable("id")Long id){ //远程调用, return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/"+id,Dept.class); } @RequestMapping("/consumer/dept/list") public List<Dept> list(){ return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list",List.class); } }
创建主启动类

@SpringBootApplication public class DeptConsumer_80 { public static void main(String[] args) { SpringApplication.run(DeptConsumer_80.class,args); } }
总结:
本次客户端远程调用服务端测试采用的是aop思想;