【Spring Cloud】--声明式服务调用Feign
2017-12-27 19:47
1381 查看
Feign 就是整合了spring cloud的Ribbon和Hystrix两个组件的更高一级封装的组件
第一步: 在consumer中引入feign 组件
整个项目结构:
pom文件:
ConsumerApplication.java
ConsumerController.java
HelloService.java
User.java
服务端:
项目结构:
User对象和上面的一样,值需要修改Controller.java就可以了。
测试:
访问http://localhost:9000/consumer 会得到如下输出:
HelloService.java
改造service中的HelloService 重命名为RefactorHelloService
RefactorHelloService.java
可以看见没有RequestMapping的声明,不仅仅减少了代码,也减少了出错的概率。
consumer中新建RefactorHelloService.java
可以看的出来,除了继承接口之外,没有任何代码。
优点显而易见,缺点是两面工程都依赖api,api产生变动,回对项目产生影响。
增加断路器功能实现自动降级:
需要改造两个类:
consumer中新增RefactorHelloFalBackService.java
consumer中RefactorHelloService.java
快速入门:
使用http://blog.csdn.net/wangpengzhi19891223/article/details/78840646中的基础工程。第一步: 在consumer中引入feign 组件
<!-- 声明式服务调用--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> </dependencies>
整个项目结构:
pom文件:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>spring-eureka-client</groupId> <artifactId>spring-eureka-client</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <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.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 加入监控开始 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- 加入监控结束 --> <!-- 增加Eureka开始 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> <!-- 增加Eureka结束 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> <!-- 容错保护机制 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> <!-- 声明式服务调用--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Camden.SR6</version> <!-- Dalston.SR1 --> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> </project>
ConsumerApplication.java
@EnableFeignClients @EnableDiscoveryClient @SpringBootApplication public class ConsumerApplication { public static void main(String[] args){ SpringApplication.run(ConsumerApplication.class, args); } }
ConsumerController.java
@RestController public class ConsumerController { @Autowired private HelloService helloService; @RequestMapping(value = "/consumer", method = RequestMethod.GET) public String helloConsumer(){ String str1 = helloService.hello("wpz"); User user1 = helloService.hello("wpz", 18); User user = new User(); user.setAge(20); user.setName("yx"); String str2 = helloService.hello(user); return helloService.hello()+str1+","+user1.getName()+user1.getAge()+","+str2; } }
HelloService.java
@FeignClient("hello-service") public interface HelloService { @RequestMapping("/hello") String hello(); @RequestMapping(value = "/hello1", method = RequestMethod.GET) String hello(@RequestParam("name") String name); @RequestMapping(value = "/hello2", method = RequestMethod.GET) User hello(@RequestHeader("name") String name, @RequestHeader("age") Integer age); @RequestMapping(value = "/hello3", method = RequestMethod.POST) String hello(@RequestBody User user); }
User.java
public class User { private String name; private Integer age; public User(){} public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
服务端:
项目结构:
User对象和上面的一样,值需要修改Controller.java就可以了。
@RestController public class HelloController { private final Logger logger = Logger.getLogger(HelloController.class); @Autowired private DiscoveryClient client; @RequestMapping(value = "/hello", method = RequestMethod.GET) public String index() throws Exception{ ServiceInstance instance = client.getLocalServiceInstance(); int sleepTime = new Random().nextInt(3000); logger.info("sleeptime"+sleepTime); Thread.sleep(sleepTime); logger.info("host:"+instance.getHost()+instance.getServiceId()+":"+instance.getPort()); return "New Hello world server!"; } @RequestMapping(value = "/hello1", method = RequestMethod.GET) public String hello(@RequestParam("name") String name){ return "hello"+name; } @RequestMapping(value = "/hello2", method = RequestMethod.GET) public User hello(@RequestHeader("name") String name, @RequestHeader("age") Integer age){ User user = new User(); user.setAge(age); user.setName(name); return user; } @RequestMapping(value = "/hello3", method = RequestMethod.POST) public String hello(@RequestBody User user){ return "hello" +user.getName()+"年龄:"+user.getAge(); } }
测试:
访问http://localhost:9000/consumer 会得到如下输出:
New Hello world server!hellowpz,wpz18,helloyx年龄:20
通过继承减少代码:
上面的例子中User对象明显是重复的,HelloService中也有很多的重复,我们可以抽取出一个单独的工程api, 两个项目中引用这个工程即可。HelloService.java
@RequestMapping("/refactor") public interface HelloService { @RequestMapping(value = "/hello4", method = RequestMethod.GET) String hello(@RequestParam("name") String name); @RequestMapping(value = "/hello5", method = RequestMethod.GET) User hello(@RequestHeader("name") String name, @RequestHeader("age") Integer age); @RequestMapping(value = "/hello6", method = RequestMethod.POST) String hello(@RequestBody User user); }
改造service中的HelloService 重命名为RefactorHelloService
RefactorHelloService.java
@RestController public class RefactorHelloService implements HelloService{ @Override public String hello(@RequestParam("name") String name){ return "hello"+name; } @Override public User hello(@RequestHeader("name") String name, @RequestHeader("age") Integer age){ User user = new User(); user.setAge(age); user.setName(name); return user; } @Override public String hello(@RequestBody User user){ return "hello" +user.getName()+"年龄:"+user.getAge(); } }
可以看见没有RequestMapping的声明,不仅仅减少了代码,也减少了出错的概率。
consumer中新建RefactorHelloService.java
@FeignClient("hello-service") public interface RefactorHelloService extends HelloService{ }
可以看的出来,除了继承接口之外,没有任何代码。
优点显而易见,缺点是两面工程都依赖api,api产生变动,回对项目产生影响。
增加断路器功能实现自动降级:
需要改造两个类:
consumer中新增RefactorHelloFalBackService.java
@Component public class RefactorHelloFalBackService implements RefactorHelloService{ public String hello(@RequestParam("name") String name){ return "error"; } public User hello(@RequestHeader("name") String name, @RequestHeader("age") Integer age){ User user = new User(); user.setName("error"); user.setAge(0); return user; } public String hello(@RequestBody User user){ return "error"; } }
consumer中RefactorHelloService.java
@FeignClient(value = "hello-service", fallback = RefactorHelloFalBackService.class) public interface RefactorHelloService{ @RequestMapping(value = "/hello1", method = RequestMethod.GET) String hello(@RequestParam("name") String name); @RequestMapping(value = "/hello2", method = RequestMethod.GET) User hello(@RequestHeader("name") String name, @RequestHeader("age") Integer age); @RequestMapping(value = "/hello3", method = RequestMethod.POST) String hello(@RequestBody User user); }
相关文章推荐
- Spring Cloud中声明式服务调用Feign
- 第九章 Spring Cloud Feign声明式调用服务
- Spring Cloud Feign 声明式服务调用
- SpringCloud之声明式服务调用Spring Cloud Feign实例
- spring cloud Feign(声明式服务调用)
- Spring Cloud 声明式服务调用 Feign
- 笔记:Spring Cloud Feign 声明式服务调用
- Spring Cloud 入门教程(六): 用声明式REST客户端Feign调用远端HTTP服务
- SpringCloud零基础上手(四)——服务发现以及Feign(声明式RESTful服务调用)
- 【图文经典版】声明式调用服务SpringCloud之Feign实例讲解
- 干货分享微服务spring-cloud(5.声明式服务调用feign)
- 使用Spring cloud Feign在后台服务之间调用传递Multipart无法传递的问题
- 使用Spring Cloud Feign作为HTTP客户端调用远程HTTP服务
- Spring Cloud Feign作为HTTP客户端调用远程HTTP服务,feign熔断器
- 使用Spring Cloud Feign作为HTTP客户端调用远程HTTP服务
- 【微服务】之五:轻松搞定SpringCloud微服务-调用远程组件Feign
- springcloud使用feign实现服务间条用,参数数据太大,无法调用成功解决方法
- 使用Spring Cloud Feign作为HTTP客户端调用远程HTTP服务
- 使用Spring Cloud Feign作为HTTP客户端调用远程HTTP服务的方法(推荐)
- Spring Cloud ZooKeeper集成Feign的坑2,服务调用了一次后第二次调用就变成了500,错误:Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is com.n