Feign是一個聲明式的Web服務客戶端。php
是什麼?java
例如我在一個服務的interace上註解@FeignClient(value = "eureka-client")
就是聲明服務名稱 告訴其餘服務等這個就是eureka-client 的服務客戶端
它使編寫Web服務客戶端變得更容易git
要使用Feign,請建立接口並註解,有可插入的註解支持,包括Feign註釋和JAX-RS註釋。github
JAX-RS註釋:JAX-RS是JAVAEE6 引入的,JAX-RS即Java API for RESTful Web Services 是Java的應用程序接口,如:web
@Path標註資源類或方法的相對路徑spring
@GET,@PUT,@POST,@DELETE 請求方式json
Feign還支持可插拔編碼器和解碼器。後端
Spring Cloud Netflix 爲 Feign提供了下面默認的配置Bean
Decoder feignDecoder: ResponseEntityDecoder
Encoder feignEncoder: SpringEncoder網絡
Spring Cloud增長了對Spring MVC註釋的支持,並使用了Spring Web中默認使用的相同HttpMessageConverters。架構
Spring Cloud集成了Ribbon和Eureka,在使用Feign時提供負載均衡的http客戶端。
白話文:微服務架構端口不少,咱們要統一端口就要用到Feign去各個服務拿接口;須要從一個服務調用另一個服務的數據也能夠直接使用Feign,也就是經過這種方式開發調用遠程服務就像是調用本地服務同樣方便。
環境
IDEA 2018.3
Gradle 4.10
springCloudVersion Finchley.RELEASE
沒有eureka-server的能夠去github下載源碼:
https://github.com/cuifuan/springcloud-tools
建立的是子項目,父項目Github下載
gradle配置 build.gradle
dependencies { implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' implementation 'org.springframework.boot:spring-boot-starter-web' implementation project(":tools-common-entity") }
建立啓動類 ToolsEurekaClientApplication.java
package store.zabbix.toolseurekaclient; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @EnableEurekaClient @RestController public class ToolsEurekaClientApplication { public static void main(String[] args) { SpringApplication.run(ToolsEurekaClientApplication.class, args); } @Value("${server.port}") private int port; @GetMapping("test") public String showPort(@RequestParam(value = "name",required = false) String name){ if (name == null) name = "Anonymous"; return "my port is "+port +" -> my name is"+name; } }
資源文件 application.yml
eureka: client: service-url: defaultZone: http://127.0.0.1:8761/eureka/ server: port: 8762 spring: application: name: eureka-client
業務接口 UserService.java
package store.zabbix.toolseurekaclient.service; import store.zabbix.common.entity.User; import java.util.List; public interface UserService { Integer createUser(User user); List<User> getUserAll(String username,Long id); Integer updateUser(User user); Integer deleteUser(List<Integer> ids); }
業務實現層 UserServiceImpl.java
package store.zabbix.toolseurekaclient.service.impl; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import store.zabbix.common.entity.User; import store.zabbix.toolseurekaclient.service.UserService; import java.util.ArrayList; import java.util.List; @Service @Slf4j public class UserServiceImpl implements UserService { @Override public Integer createUser(User user) { log.info("建立數據:{}",user.toString()); return 1; } @Override public List<User> getUserAll(String username,Long id) { log.info("查詢所有->參數1:{}->參數2:{}",username,id); User user=new User(1L,"admin","123456"); return new ArrayList<User>(){{add(user);}}; } @Override public Integer updateUser(User user) { log.info("更新數據..{}",user.toString()); return 1; } @Override public Integer deleteUser(List<Integer> ids) { log.info("刪除用戶ids->{}",ids.toString()); return 1; } }
控制層 UserController.java
package store.zabbix.toolseurekaclient.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import store.zabbix.common.entity.User; import store.zabbix.toolseurekaclient.service.UserService; import java.util.List; @RestController @RequestMapping("user") public class UserController { private final UserService userService; @Autowired public UserController(UserService userService) { this.userService = userService; } @GetMapping public List<User> getUserList(String username,Long id){ return userService.getUserAll(username,id); } @PostMapping public Integer createUser(@RequestBody User user){ return userService.createUser(user); } @PutMapping public Integer updateUser(@RequestBody User user){ return userService.updateUser(user); } @DeleteMapping public Integer deleteUSer(@RequestBody List<Integer> idList){ return userService.deleteUser(idList); } }
由上面的server.port
可知端口爲8762。
但是若是咱們有多個eureka-client,會形成後端接口訪問端口太多。
因此在這裏能夠採用feign進行統一調度
build.gradle
dependencies { implementation "org.springframework.cloud:spring-cloud-starter-openfeign" implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' implementation 'org.springframework.cloud:spring-cloud-starter-netflix-hystrix' }
新建的是子項目,依賴管理統一在父項目,子項目只聲明本身單獨使用的依賴,父項目在github能夠進行拉取,地址在上面
啓動類 ToolsRoutingApplication.java
package store.zabbix.toolsrouting; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class ToolsRoutingApplication { public static void main(String[] args) { SpringApplication.run(ToolsRoutingApplication.class, args); } }
核心就是開啓@EnableFeignClients
註解
application.yml
server: port: 8765 eureka: client: service-url: defaultZone: http://127.0.0.1:8761/eureka/ spring: application: name: service-feign
建立UserServiceClients調用eureka-client接口
package store.zabbix.toolsrouting.service; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import store.zabbix.common.entity.User; import java.util.List; @FeignClient("eureka-client") public interface UserServiceClients { @GetMapping List<User> getUserList(String name,Long id); }
@FeignClient
是核心,@FeignClient裏value的值是eureka-client的application.yml聲明的,以下:
spring: application: name: eureka-client
啓動ToolsRoutingApplication.java
發現啓動報錯
說明:
@GetMapping在這個版本可使用,其傳值要使用@RequestParam
在一些版本沒法使用@GetMapping,需使用@RequestMapping(value = "user",method = RequestMethod.GET)
UserServiceClients
接口
package store.zabbix.toolsrouting.service; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.*; import store.zabbix.common.entity.User; import java.util.List; @FeignClient("eureka-client") public interface UserServiceClients { @GetMapping("user") //@RequestMapping(value = "user",method = RequestMethod.GET) List<User> getUserList(@RequestParam("username") String name,@RequestParam("id") Long id); //這裏不加@RequestParam會報異常IllegalStateException: Method has too many Body parameters,形成沒法啓動 @PostMapping("user") Integer createUser(@RequestBody User user); @PutMapping(value = "user",produces = "application/json") Integer updateUser(@RequestBody User user); @DeleteMapping(value = "user",produces = "application/json") Integer deleteUser(@RequestBody List<Integer> ids); }
說明:PUT和DELETE請求,使用json傳輸List時或許會報錯,請在註解內加上參數produces = "application/json",如@DeleteMapping(value = "user",produces = "application/json")
package store.zabbix.toolsrouting.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import store.zabbix.common.entity.User; import store.zabbix.common.entity.bean.ResultBean; import store.zabbix.toolsrouting.service.UserServiceClients; import java.util.List; @RequestMapping("user") @RestController public class UserController { private final UserServiceClients userServiceClients; @Autowired public UserController(UserServiceClients userServiceClients) { this.userServiceClients = userServiceClients; } @GetMapping public ResultBean<List<User>> getUserList(String name, Long id) { return new ResultBean<>(userServiceClients.getUserList(name, id)); } @PostMapping public ResultBean<Integer> createUser(@RequestBody User user) { return new ResultBean<>(userServiceClients.createUser(user)); } @PutMapping public ResultBean<Integer> updateUser(@RequestBody User user){ return new ResultBean<>(userServiceClients.updateUser(user)); } @DeleteMapping public ResultBean<Integer> deleteUser(@RequestBody List<Integer> integerList){ return new ResultBean<>(userServiceClients.deleteUser(integerList)); } }
有postman的可使用下面的連接:
https://www.getpostman.com/collections/8f56e7246e290e8036f0
SpringCloud各版本出現的問題坑等不少,遇到問題儘可能自行解決,收穫纔會有不少
下面送給你們自網絡收集的圖書(侵刪):
連接:https://pan.baidu.com/s/1KmFPYhnXqxLzL4CiTEo45g 密碼:kk3u