1. 依赖
-
spring-cloud-starter-openfeign依赖<dependencies> <!-- feign --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies> -
说明
-
消费者添加spring-cloud-starter-openfeign的依赖即可,提供者不需要 -
spring-cloud-starter-openfeign的父依赖<properties> <spring-cloud.version>Hoxton.SR7</spring-cloud.version> </properties> <dependencyManagement> <dependencies> <!-- spring-cloud 父依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> -
提供者要注册到注册中心,消费者要从注册中心拉取提供者信息<properties> <spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version> </properties> <dependencies> <!-- nacos 注册中心 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies> <dependencyManagement> <!-- spring-cloud-alibaba 父依赖 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring-cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencyManagement>
-
2. 配置
-
feign-provider提供者-
application.yml主配置文件server: port: 8081 servlet: # 提供者一般不设置前缀,这是为了演示 context-path: /api/v1 spring: application: # 注册到注册中心的服务名 name: feign-provider cloud: nacos: discovery: # nacos注册中心的地址 server-addr: 120.25.207.44:8848 cluster-name: ${spring.application.name} -
启动类
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; // 开启 nacos 注册中心扫描,发现该服务 @EnableDiscoveryClient @SpringBootApplication public class FeignProviderApplication { public static void main(String[] args) { SpringApplication.run(FeignProviderApplication.class, args); } }
-
-
feign-consumer消费者-
application.yml主配置文件server: port: 8082 spring: application: # 注册到注册中心的服务名,不注册到注册中心可以不写 name: feign-consumer cloud: nacos: discovery: # nacos 注册中心的地址 server-addr: 120.25.207.44:8848 # 不将自己注册到注册中心 register-enabled: false feign: okhttp: # feign 启用 okhttp,性能最好 enabled: true -
启动类
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; // 启动 feign 客户端 @EnableFeignClients // 开启 nacos 注册中心扫描,发现该服务 @EnableDiscoveryClient @SpringBootApplication public class FeignConsumerApplication { public static void main(String[] args) { SpringApplication.run(FeignConsumerApplication.class, args); } }-
@EnableFeignClients启动feign客户端 -
@EnableDiscoveryClient开启注册中心扫描,发现该服务
-
-
3. feign组件的使用
-
feign-consumer消费者的远程调用类中用@FeignClient注解标记import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Service; @Service @FeignClient(value = "feign-provider", path = "/api/v1/provider") public interface ProviderService { }-
value = "feign-provider"的值feign-provider为提供者注册到注册中心的服务名提供者的服务名
-
path = "/api/v1/provider"是提供者的ProviderController的访问路径,/api/v1/是提供者在application.yml主配置文件配置的context-path
-
-
消费者的远程调用类中,一个参数必须使用@RequestParam或@PathVariable修饰,feign底层一个参数时会自动放进请求体中默认使用post请求(不用@RequestParam或@PathVariable有可能取到的值为null),Get请求直接报错,提供者的controller可以不用@RequestParam修饰-
@RequestParam栗子,GetMapping或者PostMapping都可以-
提供者
controllerimport org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/provider") public class ProviderController { @GetMapping("/testParam") public String testParam(String userId) { return "ProviderController_testParam_" + userId; } @PostMapping("/testPostMappingParam") public String testPostMappingParam(String userId) { return "ProviderController_testPostMappingParam_" + userId; } } -
消费者
-
远程调用类import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.*; @Service @FeignClient(value = "feign-provider", path = "/api/v1/provider") public interface ProviderService { /** * 对应 public String testParam(String userId){} * * @param userId 用户id * @return 字符串 */ @GetMapping("/testParam") String testParam(@RequestParam String userId); /** * 对应 public String testPostMappingParam(String userId){} * * @param userId 用户id * @return 字符串 */ @PostMapping("/testPostMappingParam") String testPostMappingParam(@RequestParam String userId); } -
controllerimport com.sheng.cloud.feign.service.ProviderService; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @RestController @RequestMapping("/consumer") public class ConsumerController { @Resource private ProviderService providerService; @GetMapping("/testParam") public String testParam(String userId) { return providerService.testParam(userId); } @PostMapping("/testPostMappingParam") public String testPostMappingParam(String userId) { return providerService.testPostMappingParam(userId); } }
-
-
-
@PathVariable栗子,GetMapping或者PostMapping都可以-
提供者
controllerimport org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/provider") public class ProviderController { @GetMapping("/testPathVariable/{userId}") public String testPathVariable(@PathVariable String userId) { return "ProviderController_testPathVariable_" + userId; } } -
消费者
-
远程调用类import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.*; @Service @FeignClient(value = "feign-provider", path = "/api/v1/provider") public interface ProviderService { /** * 对应 public String testPathVariable(@PathVariable String userId){} * * @param userId 用户id * @return 字符串 */ @GetMapping("/testPathVariable/{userId}") String testPathVariable(@PathVariable String userId); } -
controllerimport com.sheng.cloud.feign.service.ProviderService; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @RestController @RequestMapping("/consumer") public class ConsumerController { @Resource private ProviderService providerService; @GetMapping("/testPathVariable/{userId}") public String testPathVariable(@PathVariable String userId) { return providerService.testPathVariable(userId); } }
-
-
-
-
消费者的远程调用类中,两个参数或以上必须使用@RequestParam或@PathVariable修饰,不修饰不能启动,会直接报错。提供者的controller可以不用@RequestParam修饰-
@RequestParam栗子,GetMapping或者PostMapping都可以-
提供者
controllerimport org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/provider") public class ProviderController { @PostMapping("/login") public String login(String username, String password) { return "ProviderController_login_username: " + username + "_password: " + password; } } -
消费者
-
远程调用类import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.*; @Service @FeignClient(value = "feign-provider", path = "/api/v1/provider") public interface ProviderService { /** * 对应 public String login(String username, String password){} * * @param username 用户名 * @param password 密码 * @return 字符串 */ @PostMapping("/login") String login(@RequestParam String username, @RequestParam String password); } -
controllerimport com.sheng.cloud.feign.service.ProviderService; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @RestController @RequestMapping("/consumer") public class ConsumerController { @Resource private ProviderService providerService; @PostMapping("/login") public String login(String username, String password) { return providerService.login(username, password); } }
-
-
-
@PathVariable栗子,GetMapping或者PostMapping都可以-
提供者
controllerimport org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/provider") public class ProviderController { @GetMapping("/loginByPathVariable/{username}/{password}") public String loginByPathVariable(@PathVariable String username, @PathVariable String password) { return "ProviderController_login_username: " + username + "password: " + password; } } -
消费者
-
远程调用类import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.*; @Service @FeignClient(value = "feign-provider", path = "/api/v1/provider") public interface ProviderService { /** * 对应 public String loginByPathVariable(@PathVariable String username, @PathVariable String password){} * * @param username 用户名 * @param password 密码 * @return 字符串 */ @GetMapping("/loginByPathVariable/{username}/{password}") String loginByPathVariable(@PathVariable String username, @PathVariable String password); } -
controllerimport com.sheng.cloud.feign.service.ProviderService; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @RestController @RequestMapping("/consumer") public class ConsumerController { @Resource private ProviderService providerService; @GetMapping("/loginByPathVariable/{username}/{password}") public String loginByPathVariable(@PathVariable String username, @PathVariable String password) { return providerService.loginByPathVariable(username, password); } }
-
-
-
-
如果
消费者的远程调用类的形参是JavaBean对象,那么提供者的controller对应的方法的形参必须用@RequestBody标记,否则取到的值为null,因为feign底层默认将对象序列化成json数据进行传递。-
结果
-
不用
@RequestBody修饰不用@RequestBody修饰
-
@RequestBody修饰@RequestBody修饰
-
-
栗子
-
提供者
controllerimport com.sheng.cloud.feign.dto.UserDto; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/provider") public class ProviderController { @PostMapping("/getUser") public UserDto getUser(@RequestBody UserDto userDto) { return userDto; } } -
消费者
-
远程调用类import com.sheng.cloud.feign.dto.UserDto; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.*; @Service @FeignClient(value = "feign-provider", path = "/api/v1/provider") public interface ProviderService { /** * 对应 public UserDto getUser(@RequestBody UserDto userDto){} * * @param userDto 对象 * @return UserDto */ @PostMapping("/getUser") UserDto getUser(UserDto userDto); } -
controllerimport com.sheng.cloud.feign.dto.UserDto; import com.sheng.cloud.feign.service.ProviderService; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @RestController @RequestMapping("/consumer") public class ConsumerController { @Resource private ProviderService providerService; @PostMapping("/getUser") public UserDto getUser(@RequestBody UserDto userDto) { return providerService.getUser(userDto); } }
-
-
-











网友评论