前面我们一直使用RestTemplate去调用服务,这样做太不爽了,每一次都要将参数拼接在url中,是不是很麻烦,那么我们有没有更好的办法呢,答案是有的,那就是Feign声明式服务调用。
Feign整合了Ribbon和Hystrix,可以让我们不再需要显式地使用这两个组件。而且Feign还提供了声明式的服务调用,和SpringMVC类似,我们只需要创建一个接口并用注解方式配置它,即可完成服务提供方的接口绑定。
创建Feign模块
pom文件添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
application.properties文件
server.port=8086
spring.application.name=feign-demo
eureka.client.service-url.defaultZone=http://localhost:8081/eureka/,http://localhost:8082/eureka/
#表示开启hystrix
feign.hystrix.enabled=true
启动类加上注解@EnableFeignClients @EnableEurekaClient
@SpringBootApplication
//标明是feign客户端
@EnableFeignClients
@EnableEurekaClient
public class FeignDemoApplication {
public static void main(String[] args) {
SpringApplication.run(FeignDemoApplication.class, args);
}
}
创建一个service
//value代表映射到哪个服务,fallback是降级类(实现这个接口)
@FeignClient(value = "eureka-client",fallback = FeignServiceImpl.class)
public interface FeignService {
@RequestMapping("/run")
String run();
}
接着写一个service的实现类,就是用来降级的类
//必须加上Comopent注解,否则spring扫描不到
@Component
public class FeignServiceImpl implements FeignService {
@Override
public String run() {
return "error";
}
}
创建controller用来访问
@RestController
@RequestMapping("/feign")
public class FeignController {
@Autowired
private FeignService feignService;
@RequestMapping("/run")
public String run(){
return feignService.run();
}
}
接着启动分别启动两个注册中心,两个eureka客户端,feign客户端
我们到这发现Feign的声明式调用,用的是不是很爽,瞬间回到了springmvc的感觉,那么我们怎么去访问带参数的方法呢?
我们先来修改一下eureka客户端的代码,添加一个带参数的方法:
@RequestMapping("/getName")
public String getName(String name){
return name;
}
接着在FeignService中进行映射
@RequestMapping("/getName")
//使用注解@RequestParam映射(不加这个是映射不到的)
String getName(@RequestParam("name") String name);
接着是降级方法,就是实现一下这个方法,很简单
@Override
public String getName(String name) {
return "error";
}
controller
@RequestMapping("/getName")
public String getName(){
return feignService.getName("张三丰");
}
下面启动程序
这样就映射成功了。