什么是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思想;