JAVA服务器开发

分布式系统开发---摈弃接口拼接SpringCloud(九)

2019-01-07  本文已影响0人  Felix_

我们已经实现了从注册中心获取服务,并调用服务获取返回的数据,但是现在我们调用商品信息是这样的:

package com.felix.service;

import com.felix.fegin.GoodsFeignClient;
import com.felix.model.Goods;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

/**
 * Created by weistekweistek on 2019/1/3.
 */
@Service
public class GoodsService {
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private DiscoveryClient discoveryClient;
    @Autowired
    private GoodsFeignClient goodsFeignClient;

    //启用负载均衡后,有restTemplate自己去选择访问那个服务
    @HystrixCommand(fallbackMethod = "findGoodsByIdServiceOffline")
    public Goods findGoodsById(Long id){
    String service = "goods-service";
    String url = "http://" + service + "/goods/" + id;
    return restTemplate.getForObject(url,Goods.class);
}
    public Goods findGoodsByIdServiceOffline(Long id){
        return new Goods(id,"查询商品信息出错","","",0.0F);
    }

在获取到服务后,仍然需要自己拼接网址和对应的接口去访问数据提供者,有没有更好的方式,不需要自己拼接呢?有,它就是Feign

Feign 是一个声明web服务客户端,这便得编写web服务客户端更容易,使用Feign 创建一个接口并对它进行注解,它具有可插拔的注解支持包括Feign注解与JAX-RS注解,Feign还支持可插拔的编码器与解码器,Spring Cloud 增加了对 Spring MVC的注解,Spring Web 默认使用了HttpMessageConverters, Spring Cloud 集成 Ribbon 和 Eureka 提供的负载均衡的HTTP客户端 Feign.

说了一大堆,究竟是个什么东西,使用它能够带来什么便利,别急,先给你看下最终的结果:

//启用负载均衡后,有restTemplate自己去选择访问那个服务
    @HystrixCommand(fallbackMethod = "findGoodsByIdServiceOffline")
    public Goods findGoodsById(Long id){
        return goodsFeignClient.findGoodsById(id);
    }

哎哟,不错哟,你是不是在goodsFeignClient.findGoodsById做了拼接?并没有,那是怎么实现的呢?
首先,在现有的order模块的pom.xml中引入Feign的依赖

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
注意:这里我的SpringCloud版本是Greenwich.RC2,早期的版本Feign引入这个依赖
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
</dependency>

好了,老样子,在OrderApplication中启用Feign

package com.felix;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@EnableFeignClients
@EnableHystrix
@EnableDiscoveryClient
@SpringBootApplication
public class OrderApplication {
    @Bean
    @LoadBalanced //启用负载均衡
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}

刚才我们看到goodsFeignClient.findGoodsById(id),现在,创建一个接口GoodsFeignClient,代码如下:

package com.felix.fegin;
import com.felix.model.Goods;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@FeignClient(value = "goods-service")
public interface GoodsFeignClient {
    @RequestMapping(value = "/goods/{id}")
    public Goods findGoodsById(@PathVariable("id") Long id);
}

在这个接口里面,我们声明GoodsFeignClient为一个@FeignClient,它要访问的服务是商品服务,也就是value = "goods-service",然后,按照SpringMVC的常用注解,声明public Goods findGoodsById(@PathVariable("id") Long id);方法所对应的接口@RequestMapping(value = "/goods/{id}")
GoodsService的代码就修改为文章开始的代码

package com.felix.service;

import com.felix.fegin.GoodsFeignClient;
import com.felix.model.Goods;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class GoodsService {
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private DiscoveryClient discoveryClient;
    @Autowired
    private GoodsFeignClient goodsFeignClient;

    //启用负载均衡后,有restTemplate自己去选择访问那个服务
    @HystrixCommand(fallbackMethod = "findGoodsByIdServiceOffline")
    public Goods findGoodsById(Long id){
        return goodsFeignClient.findGoodsById(id);
    }
    public Goods findGoodsByIdServiceOffline(Long id){
        return new Goods(id,"查询商品信息出错","","",0.0F);
    }

现在,我们不再需要拼接网址和对应的参数了,按照Feign为我们提供的声明式的服务调用,使我们像调用本地接口一样的调用网络接口,摈弃了往日的接口拼接。

以上内容转载请注明出处,同时也请大家不吝你的关注和下面的赞赏
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

上一篇下一篇

猜你喜欢

热点阅读