Spring Cloud——声明式的服务调用

一、声明式的服务

  Feign是一个声明性的Web服务客户端。它使编写Web服务客户端变得更容易。它具有可插入的注释支持,包括Feign注释和JAX-RS注释。Feign还支持可插拔编码器和解码器。另外它还集成了Ribbon,Eureka及Hystrix,所以feign也能实现了负载均衡,服务注册,断路器功能。(感觉很棒,集成这么多也就意味着pom.xml文件夹里需要依赖的文件变少了)

  既然叫声明式的服务调用,那么,作者想,只需要把接口列出来,然后对外声称,这些接口是我要发送的,不需要多余的代码,可能仅仅就提供一个标记。就可以完成整个功能!

二、搭建一个Feign的例子并说明

为了扩展多参数的接口,我们首先在服务端的Controller类中加入处理客户端的接口处理类,代码如下(只是部分):

@RequestMapping(value="/hello")
public String index() {
    return "hello server1";
}

@RequestMapping(value="/hello1",method = RequestMethod.GET)
public String index1(@RequestParam String name) {
    return "Hello"+name;
}
	
@RequestMapping(value="/hello2",method=RequestMethod.GET)
public User index2(@RequestHeader Long id,@RequestHeader String name) {
	return new User(id,name);
}
	
@RequestMapping(value="/hello3",method=RequestMethod.POST)
public String index3(@RequestBody User user) {
	return "Hello "+ user.getId()+", "+user.getName();
}

可参考之前服务端的例子,可参考:https://blog.csdn.net/notMoonHeart/article/details/84954217

增加好服务之后,我们开始搭建Fegin。

  1.创建一个Spring Boot工程,命名为:feign-consumer,并更改pom.xml文件,引入所需要的包。(因为Feign集成了很多功能的缘故,所以引用的依赖会特比少),代码如下:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
	
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
        
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>2.0.0.RELEASE</version>
</dependency>

2.创建声明接口的接口,命名为HelloService.java,代码如下:

package com.example.demo.web;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient("hello-service")
public interface HelloService {
	
	@RequestMapping(value="/hello", method = RequestMethod.GET)
	String hello();
	
	@RequestMapping(value = "/hello1", method= RequestMethod.GET) 
	String hello(@RequestParam("name") String name) ; 
	
	@RequestMapping(value = "/hello2", method= RequestMethod.GET)
	User hello(@RequestHeader("id") Long id, @RequestHeader("name") String name); 
	
	@RequestMapping(value = "/hello3", method= RequestMethod.POST)
	String hello(@RequestBody User user); 
}

分析:上面的代码就是声明式的服务,在接口中声明,然后只需要注入实例,调用声明的方法即可发送请求,不需要再写之前的getForEntity。。。等方法来发送请求。所以这里一切的声明,都是通过@FeignClient注解实现的。

3.创建Controller类,发送请求,命名:HelloContronller.java 代码如下:

package com.example.demo.web;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloContronller {
	
	@Autowired
	HelloService helloService;
	
	@RequestMapping(value="/feign-consumer", method=RequestMethod.GET)
	public String helloConsumer() {
		return helloService.hello();
	}
	
	@RequestMapping(value="/feign-consumer1", method=RequestMethod.GET)
	public String helloConsumer1() {
		StringBuilder sb = new StringBuilder();
		sb.append(helloService.hello()).append("---");
		sb.append(helloService.hello("nana")).append("---");
		sb.append(helloService.hello(10L, "nana")).append("---");
		sb.append(helloService.hello(new User(11L, "nana2")));
		return sb.toString();
	}
}

4.启动类增加注解,@SpringBootApplication,@EnableFeignClients,@EnableDiscoveryClient(这里就不沾代码了)

5.修改配置文件application.properties,代码如下:

server.port=8090
spring.application.name=feign-consumer

eureka.client.service-url.defaultZone=http://localhost:8088/eureka/eureka

6.启动eureka和2个服务工程,然后再启动feign-consumer,访问http://localhost:8090/feign-consumerhttp://localhost:8090/feign-consumer1,会发现feign是实现负载均衡功能的。

三、feign实现fallback

feign既然集成了Hystrix,并且声明类的服务把发送请求封装成了接口形式,那么要实现断路器功能,它应该怎么实现呢?下面通例子来看看。

1.开启Hystrix,feign虽然集成了Hystrix,但是默认情况下是关闭的(作者被这个坑惨了),修改application.properties配置文件,增加如下代码:

feign.hystrix.enabled=true

2.开启之后,只需要写一个实现声明接口的类,再配置属性就可以开启fallback功能了。创建实现声明类,命名为HelloServiceFillback.java,代码如下:

package com.example.demo.web;

public class HelloServiceFillback implements HelloService{

	@Override
	public String hello(User user) {
		return user.toString()+" error";
	}
	
	@Override
	public User hello(Long id, String name) {
		return new User(99L, "error");
	}
	
	@Override
	public String hello(String name) {
		return name+": error";
	}
	
	@Override
	public String hello() {
		return "error";
	}

}

3.配置fallback属性,在声明接口中,修改配置属性,如下:

@FeignClient(name="hello-service",fallback=HelloServiceFillback.class)
public interface HelloService {
    ....
}

4.在启动类中要用Spring bean声明fallback实现类的实例,在FeignConsumerApplication.java 增加如下代码:

@Bean
public HelloServiceFillback fallback() {
	return new HelloServiceFillback();
}

5.然后启动项目,帮刚才启动的server服务类全部粗暴的干掉,访问http://localhost:8090/feign-consumer1,会出现自定义的返回信息,如下:

猜你喜欢

转载自blog.csdn.net/notMoonHeart/article/details/85062052