其实服务消费者,服务提供者只是业务层面上的定义,他们本身的身份是可以有两层的,例如 服务A、B、C , A调用B时,A作为消费者,B作为提供者 ,C调用A时,C作为消费者,A作为提供者,这里的服务A就有两重身份。所以提供者、消费者代码层面上,其实没有本质区别。只有业务上的区分而已。
创建服务消费者(与创建服务消费者步骤相同)
第一步:从上一步创建的父工程里 创建一个新的module
创建module ,并且取名为consumer
在这里插入图片描述在新建的consumer工程的pom.xml中添加提供者依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
</dependencies>
第二步:创建yml文件,添加提供者配置信息
在consumer的resource文件夹中创建application.yml文件,并添加以下信息:
server:
port: 8020
spring:
application:
name: consumer
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
配置信息说明:
- server-port: 服务提供者的端口号
- spring-application-name: 当前服务注册在EurekaServer的名称
- eureka-client-service-url-defaultZone: 注册中心的地址
- eureka-instance-prefer-ip-address: 是否将当前服务的ip注册到Eureka Server中
第三步,配置启动类,以及配置调用信息,启动服务提供者
在consumer 的java 文件夹中,创建一个名字以Application 结尾的java 类,b并且把RestTemplate 实例注入到 IoC容器中, 这是能实现模块间调用的关键 添加如下信息:
package com.southwind;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args){
SpringApplication.run(ConsumerApplication.class);
}
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
在java 文件夹中,新建controler 文件,创建ConsumerHandler 类,使用RestTemplate 类实现模块间的调用
ConsumerHandler 代码如下:
package com.southwind.controller;
import com.southwind.entity.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import java.util.Collection;
@RestController
@RequestMapping("/consumer")
public class ConsumerHandler {
@Autowired
private RestTemplate restTemplate;
//在这里通过RestTemplate的方法调用 eruekaclient 模块的方法
//第一种方法,使用getForEntity,不是返回 ResponseEntity<T>类型,所以需要通过调用.getBody()方法
@GetMapping("/findAll")
public Collection<Student> findAll(){
return restTemplate.getForEntity("http://localhost:8010/student/findAll",Collection.class).getBody();
}
//第二种方法,使用getForObject ,因为此方法返回值就是泛型 ,所以直接返回即可
@GetMapping("/findAll2")
public Collection<Student> findAll2(){
return restTemplate.getForObject("http://localhost:8010/student/findAll",Collection.class);
}
@GetMapping("/findById/{id}")
public Student findById(@PathVariable("id") long id){
return restTemplate.getForEntity("http://localhost:8010/student//findById/{id}",Student.class,id).getBody();
}
@GetMapping("/findById2/{id}")
public Student findById2(@PathVariable("id") long id){
return restTemplate.getForObject("http://localhost:8010/student/findById/{id}",Student.class,id);
}
@PostMapping("/save")
public void save(@RequestBody Student student){
restTemplate.postForEntity("http://localhost:8010/student/save",student,null).getBody();
}
@PostMapping("/save2")
public void save2(@RequestBody Student student){
restTemplate.postForObject("http://localhost:8010/student/save",student,void.class);
}
@PutMapping("/update")
public void update(@RequestBody Student student){
restTemplate.put("http://localhost:8010/student/update",student);
}
@DeleteMapping("deleteById/{id}")
public void deleteById(@PathVariable("id") long id){
restTemplate.delete("http://localhost:8010/student/deleteById/{id}",id);
}
}
最后,先启动注册中心eurekaserver ,然后再启动eurekaclient ,再启动 consumer,在网页上输入 http://localhost:8761
即可看到服务消费者已经注册进了注册中心
在这里插入图片描述
至此,服务消费者已经实现。
这里说明一下,服务消费者 与上文 RestTemplate 实现模块间的调用的代码是一样的,唯一的区别是,消费者是把自己注册进了注册中心,也就是多了一个yml配置。实际上,实现消费者调用提供者,依旧是通过RestTemplate 实现的。 这是嵌在spring boot依赖里面的方法,也是实现模块间调用的关键,这就是为啥spring Cloud 不能脱离于springboot 框架的原因之一
这里测试一下:
查询:
测试成功