我们已经实现了从注册中心获取服务,并调用服务获取返回的数据,但是现在我们调用商品信息
是这样的:
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
为我们提供的声明式的服务调用,使我们像调用本地接口一样的调用网络接口,摈弃了往日的接口拼接。
以上内容转载请注明出处,同时也请大家不吝你的关注和下面的赞赏
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
网友评论