32.微服務之間的呼叫方式RestTemplate和FeignClient
SpringCloud服務間的呼叫有兩種方式:RestTemplate和FeignClient。不管是什麼方式,他都是通過REST介面呼叫服務的http介面,引數和結果預設都是通過jackson序列化和反序列化。因為Spring MVC的RestController定義的介面,返回的資料都是通過Jackson序列化成JSON資料。
一、RestTemplate
使用這種方式,只需要定義一個RestTemplate的Bean,設定成LoadBalanced即可。
如下示例:
1 2 3 4 5 6 7 8 | @Configuration public class SomeCloudConfiguration { @LoadBalanced @Bean RestTemplate restTemplate() { return new RestTemplate(); } } |
這樣我們就可以在需要用的地方注入這個bean使用:
1 2 3 4 5 6 7 8 | public class SomeServiceClass { @Autowired private RestTemplate restTemplate; public String getUserById(Long userId) { UserDTO results = restTemplate.getForObject("http://users/getUserDetail/" + userId, UserDTO.class); return results; } } |
其它示例參考:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | @SpringBootApplication public class SleuthClientApplication { @Bean public RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(SleuthClientApplication.class, args); } } @RestController class HomeController { private static final Log log = LogFactory.getLog(HomeController.class); @Autowired private RestTemplate restTemplate; private String url="http://localhost:9986"; @RequestMapping("/service1") public String service1() throws Exception { log.info("service1"); Thread.sleep(200L); String s = this.restTemplate.getForObject(url + "/service2", String.class); return s; } } |
二、FeignClient
除了上面的方式,我們還可以用FeignClient。
1 2 3 4 5 6 7 | @FeignClient(value = "users", path = "/users") public interface UserCompositeService { @RequestMapping(value = "/getUserDetail/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) UserDTO getUserById(@PathVariable Long id); } |
我們只需要使用@FeignClient定義一個介面,Spring Cloud Feign會幫我們生成一個它的實現,從相應的users服務獲取資料。
其中,@FeignClient(value = “users”, path = “/users/getUserDetail”)裡面的value是服務ID,path是這一組介面的path字首。在下面的方法定義裡,就好像設定Spring MVC的介面一樣,對於這個方法,它對應的URL是/users/getUserDetail/{id}。然後,在使用它的時候,就像注入一個一般的服務一樣注入後使用即可:
1 2 3 4 5 6 7 8 9 | public class SomeOtherServiceClass { @Autowired private UserCompositeService userService; public void doSomething() { // ..... UserDTO results = userService.getUserById(userId); // other operation... } } |