1.环境搭建
- 再创建一个子model
- 导入依赖,不需要连接数据库,所以只需要实体类+web的依赖即可
<dependencies> <!--实体类dept--> <dependency> <groupId>com.thhh</groupId> <artifactId>springcould-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!--spring boot的web启动器--> <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>
- 项目配置文件配置,只需要配置端口号即可
server: port: 80
2.代码实现
- 接下来就是编写消费者的controller了,注意:消费者子model中没有service层,service层在提供者中,所以我们在消费者的controller层想要调用服务者提供的服务,我们需要通过请求服务者提供的API实现
- 但是我们怎么在消费者的controller中的方法中模拟浏览器向运行在其他服务器上8001端口的服务站发送请求呢?
- 在前面学习dubbo+zookeeper的时候,我们是通过注册中心完成提供者和消费者之间的联系的,即先将服务者向外提供的服务注册到注册中心中,而消费者使用dubbo的注解@Reference将注册中心中对应的实例注入到消费者的controller中,使得消费者就可以调用提供者向外提供的服务
- 但是在讲解"SpringCloud(2) —— SpringCloud入门概述"的时候我们就说过了,Dubbo和SpringCloud最大的区别就是:Spring Cloud 抛弃了Dubbo的RPC通信,采用的是基于HTTP的REST方式
- 而在实际使用SpringCloud的时候,我们使用的步骤也很简单,直接在controller中添加一个RestTemplate对象的引用,然后自己编写一个config类将RestTemplate对象注入到spring容器中就可以使用这个类来模拟浏览器向服务器发送HTTP请求,这样就实现了客户端只需要知道服务端对应服务的请求就可以实现对于服务端提供的服务的调用
【补充:RestTemplate 】
- RestTemplate 是从 Spring3.0 开始支持的一个 HTTP 请求工具,它提供了常见的REST请求方案的模版,例如 GET 请求、POST 请求、PUT 请求、DELETE 请求以及一些通用的请求执行方法 exchange 以及 execute。RestTemplate 继承自 InterceptingHttpAccessor 并且实现了 RestOperations 接口,其中 RestOperations 接口定义了基本的 RESTful 操作,这些操作在 RestTemplate 中都得到了实现
- Spring RestTemplate详解1
- Spring RestTemplate详解2
- 小结:RestTemplate就是用来模拟浏览器发送HTTP请求的一个包装类,它将整个步骤精简到只需要调用RestTemplate.xxxForObject()就可以实现,XXX就是请求的方式,比如:get、post等,它是spring提供的一个简单的restful服务模板
- 3个参数可以简单理解为:从哪里获取服务器响应,本次请求需要携带的参数(可缺省,有对应的重载),服务器返回的数据的类型
-
为什么要定义一个config类将将RestTemplate对象注入到spring容器中?原因当然是这个对象没有被spring boot自动装配到spring容器中,我们可以通过它的源码发现没有一个@Bean注解
-
好处:这完全实现了服务者和消费者的解耦,因为消费者获取服务者的服务就是按照HTTP请求的方式获取的;而原来使用dubbo+zookeeper的时候,我们需要在客户端写一个服务端提供服务的service的引用,然后在客户端调用该service的方法实现消费者对于提供者提供的服务的消费,这样显然两边是有耦合的
-
编写一个config类,将RestTemplate注入spring容器中
package com.thhh.springcould.controller; import com.thhh.springcould.pojo.Dept; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.client.RestTemplate; import java.util.List; @Controller public class DeptConsumerController { //消费者没有service层,需要使用 @Autowired private RestTemplate restTemplate; private static final String REST_URL_PREFIX = "http://localhost:8001/"; //请求服务者提供的服务的url的固定前缀,就是服务者程序的主机名+端口名。它的后面还应该接上对应服务的请求url/映射的地址 @RequestMapping("/consumer/dept/queryById/{deptno}") public Dept getDeptById(@PathVariable("deptno") long id){ //根据id查询部门信息 return restTemplate.getForObject(REST_URL_PREFIX+"/dept/queryById/"+id,Dept.class);//参数1:请求服务者服务的uri,参数2:返回的数据的类型的class对象 //该方法有重载,参数1为前缀,参数2为请求携带的参数,参数3为返回的数据的类型的class对象 } @RequestMapping("/consumer/dept/add") public boolean addDept(Dept dept){ //新增部门 return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add",dept,boolean.class); } @RequestMapping("/consumer/dept/queryAll") public List<Dept> queryAll(){ return restTemplate.getForObject(REST_URL_PREFIX+"/dept/queryList",List.class); } }
-
编写消费者的spring boot项目的入口程序
package com.thhh.springcould; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DeptConsumer_80 { public static void main(String[] args) { SpringApplication.run(DeptConsumer_80.class,args); } }
-
启动测试
server: port: 8002
将消费者放在8002端口上
-
测试是否能够通过消费者获取到提供者提供的服务
-
通过上面的例子我们就实现了通过spring cloud的方式实现提供者和消费者之间的通信,这有别于前面学习的dubbo+zookeeper通过注册中心实现的方式,spring cloud利用了spring提供的RestTemplate对象模拟浏览器向服务器发送对应的服务请求,整个流程为:客户端–(请求消费者的API)–>消费者程序–(请求提供者的API)–>提供者,但是真正的服务提供的API是封装在消费者程序中的,它向正在的提供者进行访问的时候的URI也是封装在消费者程序中的,这样提高了服务的安全性
3.对比dubbo+zookeeper和spring cloud实现服务注册与发现
- 相比于dubbo+zookeeper,使用spring cloud中的RestTemplate,使用步骤相对更加的简单,并且封装性更好
- dubbo+zookeeper中消费者需要从远程注入提供者提供的服务实例对象才能消费服务,而spring cloud中的RestTemplate只需要服务站提供服务的API即可消费服务,并且将所有的操作都放在了提供者中;而消费者程序,只是起到了一个代替真实用户向提供者发送服务请求的作用