RestTemplate实现服务之间的调用

开始系统学习微服务相关的知识点,现在微服务中的主流框架是 Spring Cloud 和 Dubbo,因为公司用的是 Spring Cloud,我就从 Spring Cloud 着手实战微服务。

先来看两个服务之间的调用,Spring Boot 是怎么帮我们做的?存在什么弊端?要如何解决?

RestTemplate

Spring Boot 在 org.springframework.web.client.RestTemplate 中提供了 RestTemplate 能够帮助我们调用 Restful 形式的服务接口。

先看一下项目结构:

1
2
3
4
.
├── microcloud-consumer # 服务消费者
├── microcloud-provider # 服务提供者
└── pom.xml # 父pom统一管理版本等

microcloud-provider

服务提供者的配置如下所示,端口为 7900,并且给一个别名 microcloud-provider。

1
2
3
4
5
server:
  port: 7900
spring:
  application:
    name: microcloud-provider

它提供了一个 Rest 接口

1
2
3
4
5
6
7
8
@RestController
public class UserController {

    @GetMapping("/user/{id}")
    public User getUser(@PathVariable(value = "id") String id){
        return new User(id);
    }
}

访问 http://localhost:7900/user/1 返回 {“id”:”1”,”name”:null}。

microcloud-consumer

现在 Consumer 要想办法调用 Provider 提供的接口,配置文件和 Controller 如下:

1
2
3
4
5
server:
  port: 8900
spring:
  application:
    name: micro-consumer

Spring Boot 提供了 RestTemplate 帮助我们调用 Rest 的接口。

1
2
3
4
5
6
7
8
9
10
11
12
@RestController
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/order/{id}")
    public User getCustomer(@PathVariable("id") String id){
        User user = restTemplate.getForObject("http://localhost:7900/user/" + id, User.class);
        return user;
    }
}

RestTemplate 需要实例化,然后作为 Bean 交给 Spring 管理才能注入。

1
2
3
4
5
6
7
8
9
10
11
@SpringBootApplication
public class ConsumerApp {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApp.class, args);
    }

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

这样调用由什么问题?

我们的调用主要使用了这个方法 restTemplate.getForObject("http://localhost:7900/user/" + id, User.class); ,其中需要提供服务提供者的 URL 路径。

这样就有问题了,这个路径是写死的,服务是固定的,更换不方便,即使我将路径方法配置文件中,任然不方便。

1
2
3
4
5
6
7
server:
  port: 8900
spring:
  application:
    name: micro-consumer
user:
  usr: http://localhost:7900/user/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@RestController
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

    @Value("${user.url}")
    private String url;

    @GetMapping("/order/{id}")
    public User getCustomer(@PathVariable("id") String id){
//        User user = restTemplate.getForObject("http://localhost:7900/user/" + id, User.class);
        User user = restTemplate.getForObject(url + id, User.class);
        return user;
    }
}

怎么样的方式更方便的呢?就是使用服务注册与发现方法,下篇文章就讲如何用 Eureka 实现服务的注册与发现,并对现有的项目进行改造。

posted @ 2019-11-05 23:11  深页  阅读(89)  评论(0编辑  收藏  举报