<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> </dependency>
@MapperScan("com.itmuch.contentcenter.dao") @SpringBootApplication @EnableFeignClients// (defaultConfiguration = GlobalFeignConfiguration.class) @EnableBinding({Source.class}) public class ContentCenterApplication {
@FeignClient(name = "user-center") public interface UserCenterFeignClient { /** * http://user-center/users/{id} * * @param id * @return */ @GetMapping("/users/{id}") UserDTO findById(@PathVariable Integer id); }
private final UserCenterFeignClient userCenterFeignClient; // 1. 代码不可读 // 2. 复杂的url难以维护:https://user-center/s?ie={ie}&f={f}&rsv_bp=1&rsv_idx=1&tn=baidu&wd=a&rsv_pq=c86459bd002cfbaa&rsv_t=edb19hb%2BvO%2BTySu8dtmbl%2F9dCK%2FIgdyUX%2BxuFYuE0G08aHH5FkeP3n3BXxw&rqlang=cn&rsv_enter=1&rsv_sug3=1&rsv_sug2=0&inputT=611&rsv_sug4=611 // 3. 难以相应需求的变化,变化很没有幸福感 // 4. 编程体验不统一 UserDTO userDTO = this.userCenterFeignClient.findById(userId);
@FeignClient(name = "user-center", configuration = GlobalFeignConfiguration.class) public interface UserCenterFeignClient { /** * http://user-center/users/{id} * * @param id * @return */ @GetMapping("/users/{id}") UserDTO findById(@PathVariable Integer id); }
/** * feign的配置类 * 这个类别加@Configuration注解了,不然必须挪到@ComponentScan能扫描的包之外 */ public class GlobalFeignConfiguration { @Bean public Logger.Level level(){ // 让feign打印全部请求的细节 return Logger.Level.FULL; } }
logging: level: com.itmuch.contentcenter.feignclient.UserCenterFeignClient: debug
EnableFeignClientsjava
// 扫描mybatis哪些包里面的接口 @MapperScan("com.itmuch.contentcenter.dao") @SpringBootApplication @EnableFeignClients(defaultConfiguration = GlobalFeignConfiguration.class) @EnableBinding({Source.class}) public class ContentCenterApplication {
/** * feign的配置类 * 这个类别加@Configuration注解了,不然必须挪到@ComponentScan能扫描的包之外 */ public class GlobalFeignConfiguration { @Bean public Logger.Level level(){ // 让feign打印全部请求的细节 return Logger.Level.FULL; } }
// 扫描mybatis哪些包里面的接口 @MapperScan("com.itmuch.contentcenter.dao") @SpringBootApplication @EnableFeignClients// (defaultConfiguration = GlobalFeignConfiguration.class) @EnableBinding({Source.class}) public class ContentCenterApplication {
@GetMapping("test-get") public UserDTO query(UserDTO userDTO) { return testUserCenterFeignClient.query(userDTO); }
import com.itmuch.contentcenter.domain.dto.user.UserDTO; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.SpringQueryMap; import org.springframework.web.bind.annotation.GetMapping; @FeignClient(name = "user-center") public interface TestUserCenterFeignClient { @GetMapping("/q") UserDTO query(@SpringQueryMap UserDTO userDTO); }
@FeignClient(name = "user-center") public interface UserFeignClient { @RequestMapping(value = "/q", method = RequestMethod.GET) public UserDTO query(@RequestParam("id") Long id, @RequestParam("username") String username); }
下面来讨论如何使用Feign构造包含多个参数的POST请求。假设服务提供者的Controller是这样编写的:git
@RestController public class UserController { @PostMapping("/post") public User post(@RequestBody User user) { ... } }
@FeignClient(name = "microservice-provider-user") public interface UserFeignClient { @RequestMapping(value = "/post", method = RequestMethod.POST) public User post(@RequestBody User user); }
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; // 脱离ribbon的使用 @FeignClient(name = "baidu", url = "http://www.baidu.com") public interface TestBaiduFeignClient { @GetMapping("") String index(); }
feign: sentinel: # 为feign整合sentinel enabled: true client: config: # 全局配置 default: loggerLevel: full requestInterceptors: - com.itmuch.contentcenter.feignclient.interceptor.TokenRelayRequestIntecepor httpclient: # 让feign使用apache httpclient作请求;而不是默认的urlconnection enabled: true # feign的最大链接数 max-connections: 200 # feign单个路径的最大链接数 max-connections-per-route: 50
从实践上看,采用feign的方式更优雅(feign内部也使用了ribbon作负载均衡)。github