述
上文中,初步的使用了Feign,在写HelloService接口的时候,可以发现,代码可以直接从服务提供者中复制过来.
这些可以复制的代码Spring Cloud Feign对它进行了进一步的抽象,这里就用到了Feign的继承特性,那么下面就来看下如何使用Feign的继承特性,进一步简化代码
环境搭建
新建工程
新建一个子工程,名字是hello-service-api
,跟之前一样,添加到父工程下面.
创建公共接口
新建一个HelloService接口,内容如下:1
2
3
4
5
6
7
8
9
10
11
12
13@RequestMapping("helloService")
public interface HelloSerivce {
@GetMapping("/hello1")
String hello(@RequestParam("name") String name);
@GetMapping("/hello2")
User hello(@RequestHeader("name") String name, @RequestHeader("job") String job, @RequestHeader("id") Long id) throws UnsupportedEncodingException;
@PostMapping("/hello3")
String hello(@RequestBody User user);
}
这个就是我们上篇文章中的HelloService的内容,只不过加了一个请求前缀.
服务提供者修改
首先需要在服务提供者工程中,引入hello-service-api的依赖,如下:1
2
3
4
5
6<!-- hello service -->
<dependency>
<groupId>com.hello.service</groupId>
<artifactId>hello-service-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
然后新建一个Controller,实现刚才创建的helloService接口,具体如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19@RestController
public class HelloController implements HelloSerivce {
@Override
public String hello(@RequestParam String name) {
return "name:" + name;
}
@Override
public User hello(@RequestHeader String name, @RequestHeader String job, @RequestHeader Long id) throws UnsupportedEncodingException {
return new User(id, URLDecoder.decode(name,"UTF-8"), URLDecoder.decode(job,"UTF-8"));
}
@Override
public String hello(@RequestBody User user) {
return user.getName();
}
}
实现HelloSerivce中的这几个方法, 然后方法的具体实现还是和之前的是一样的,不同的地方是,这里不需要再方法上加@RequestMapping
注解,这些注解在HelloSerivce接口中都有了
方法中的参数@RequestHeader
和@RequestBody
注解还是要添加,@RequestParam
注解可以不添加
服务消费者修改
首先需要把hello-service-api的依赖引进来:1
2
3
4
5<dependency>
<groupId>com.hello.service</groupId>
<artifactId>hello-service-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
消费者中新建一个HelloService2,然后继承上面创建的HelloSerivce,代码如下:1
2
3@FeignClient("eureka-client")
public interface HelloService2 extends HelloSerivce {
}
这个接口是不需要添加任何方法,方法都在父接口中,这里只需要在类上面添加@FeignClient
注解,来绑定服务即可.
最后在Controller中提供调用的接口:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23@RestController
@RequestMapping("/hello")
public class HelloController {
@Autowired
private HelloService2 helloService;
@GetMapping("/hello1")
public String hello1(){
return helloService.hello("张三");
}
@GetMapping("/hello2")
public User hello2() throws UnsupportedEncodingException {
return helloService.hello(URLEncoder.encode("张三", "UTF-8"), URLEncoder.encode("测试", "UTF-8"), 1L);
}
@GetMapping("/hello3")
public String hello3(){
User user = new User(1L, "张三", "开发");
return helloService.hello(user);
}
}
测试
依次启动,服务注册中心,服务提供者,消费者,然后请求上面这个controller中的几个接口. 看一下返回值:
总结
总的实现过程呢就是先创建一个提供者和消费者公用的接口, 然后提供者的Controller实现公共接口, 然后消费者创建接口继承这个公共接口.
这种方式用起来方便,但是耦合度太高,此时如果服务提供者修改了一个接口的定义,服务消费者可能也得跟着变化,进而带来很多未知的工作量,因此小伙伴们在使用继承特性的时候,要慎重考虑.