Feign是一個web請求的工具,可以將請求指定到具體的服務(wù)上去
話題1:什么是Feign ?
Feign 是一個聲明web服務(wù)客戶端,這使得編寫web服務(wù)客戶端更容易
- 可使用Feign 創(chuàng)建一個接口并對它進行注解
- 可插拔的注解支持包括Feign注解與JAX-RS注解
- Feign還支持可插拔的編碼器與解碼器,
- Spring Cloud 增加了對 Spring MVC的注解,Spring Web 默認使用了HttpMessageConverters,
- Spring Cloud 集成 Ribbon 和 Eureka 提供的負載均衡的HTTP客戶端 Feign.
話題2:name和url的關(guān)系:
- 不寫url時:name就是調(diào)用的服務(wù)的名稱
- 編寫url時:name就是url指定服務(wù)的別名(現(xiàn)在版本聲明:不能單獨寫url,name必須寫)
@FeignClient(name = "xxxx", url = "http://localhost:8761/", configuration = MyFeignConfiguration2.class)
話題3:如何使用Feign?
- 3.1 引入Feigon的Jar包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
- 3.2 創(chuàng)建接口,指定要調(diào)用的服務(wù)名稱
@FeignClient("server-provider")
public interface ConsumeFeign {
@RequestMapping(value = "/simple/{id}", method = RequestMethod.GET)
public User findById(@PathVariable Long id);
}
- 3.3 將方法的調(diào)用改成接口的實現(xiàn)
@RestController
public class ConsumeController {
@Autowired
private ConsumeFeign consumeFeign;
@GetMapping("/movie/{id}")
public User findById(@PathVariable Long id) {
return this.consumeFeign.findById(id);
}
}
- 3.4 在入口程序上添加@EnableFeignClients
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class ServerConsumeFeigonApplication {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ServerConsumeFeigonApplication.class, args);
}
}
- 3.5 對比前后,請求方式發(fā)生的變化
#以前使用RestTemplate對象去找對應(yīng)的服務(wù)和請求方法
@GetMapping("/movie/{id}")
public User findById(@PathVariable Long id) {
return this.restTemplate.getForObject("http://localhost:7911/simple/" + id, User.class);
}
#現(xiàn)在使用feign,去發(fā)現(xiàn)服務(wù),然后映射到相關(guān)請求上
@FeignClient("server-provider")
public interface ConsumeFeign {
@RequestMapping(value = "/simple/{id}", method = RequestMethod.GET)
public User findById(@PathVariable("id") Long id);
}
@GetMapping("/movie/{id}")
public User findById(@PathVariable Long id) {
return this.consumeFeign.findById(id);
}
話題4:使用Feign的三個坑?
- 使用@GetMapping("/movie/{id}")標注不可以
- 使用@PathVariable不添加@PathVariable("id")int id
- 參數(shù)中傳遞復(fù)雜變量public User findByUser(User user) {},即使在controller上標記是GET請求,但是在Fegin上面的響應(yīng)也是POST
#不能使用,啟動報錯
@GetMapping("/movie/{id}")
public User findById(@PathVariable Long id) {
return this.restTemplate.getForObject(this.userServicePath + id, User.class);
}
#可以使用,啟動不報錯
@RequestMapping(value="/movie/{id}",method = RequestMethod.GET)
public User findById2(@PathVariable("id") Long id) {
return this.restTemplate.getForObject(this.userServicePath + id, User.class);
}
#不可以使用,運行報錯
@RequestMapping(value="/movie/{id}",method = RequestMethod.GET)
public User findByUser(User user) {
return this.restTemplate.getForObject(this.userServicePath + user.getId(), User.class);
}
話題5:使用Feign的自定義配置(feigon標注)
SpringCloud根據(jù)FeignClientsConfiguration為每一個命名的客戶端創(chuàng)建一個新的整體ApplicationContext.
這包含(其他)feign Decoder,feigon Encoder和feign COntract
也就是說:
- 1.先創(chuàng)建一個ConsumeFeign接口,在里面實現(xiàn)我們自己的數(shù)據(jù)請求
public interface ConsumeFeign {
@RequestLine("GET /simple/{id}")
public User findById(@Param("id") Long id);
}
- 2.創(chuàng)建自定義的FeignConfiguration
public class MyFeignConfiguration {
@Bean // Feign協(xié)議
public Contract feignContract() {
return new feign.Contract.Default();
}
@Bean // Feign日志等級
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
- 3.然后在接口中指明我們要請求的服務(wù)和使用的FeignConfiguration
@FeignClient(name = "microservice-provider-user", configuration = MyFeignConfiguration.class)
public interface ConsumeFeign {
@RequestLine("GET /simple/{id}")
public User findById(@Param("id") Long id);
}
- 4.最后調(diào)用相關(guān)的feign
@GetMapping("/movie/{id}")
public User findById(@PathVariable Long id) {
return (User) this.consumeFeign.findById(id);
}
- 5.總結(jié):調(diào)用服務(wù)的時候
- 5.1、根據(jù)consumeFeign調(diào)用方法,
- 5.2、使用Feign自帶的標注@RequestLine("GET /simple/{id}")去@FeignClient中去找到相關(guān)的配置
- 5.3、使用@FeignClient的配置去使用自定義Feign的Contract協(xié)議
話題6:使用Feign的自定義配置(Spring標注)
- 1.先創(chuàng)建一個ConsumeFeign接口,在里面實現(xiàn)我們自己的數(shù)據(jù)請求
public interface ConsumeFeign2 {
@RequestMapping(value = "/eureka/apps/{serviceName}")
public String findServiceInfoFromEurekaByServiceName(@PathVariable("serviceName") String serviceName);
}
- 2.創(chuàng)建自定義的FeignConfiguration
public class MyFeignConfiguration2 {
@Bean
public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
return new BasicAuthRequestInterceptor("admin", "admin");
}
}
- 3.然后在接口中指明我們要請求的服務(wù)和使用的FeignConfiguration
@FeignClient(name = "xxxx", url = "http://localhost:8761/", configuration = MyFeignConfiguration2.class)
public interface ConsumeFeign2 {
@RequestMapping(value = "/eureka/apps/{serviceName}")
public String findServiceInfoFromEurekaByServiceName(@PathVariable("serviceName") String serviceName);
}
- 4.最后調(diào)用相關(guān)的feign
@GetMapping("/{serviceName}")
public String findServiceInfoFromEurekaByServiceName(@PathVariable String serviceName) {
return this.consumeFeign2.findServiceInfoFromEurekaByServiceName(serviceName);
}
- 5.總結(jié):調(diào)用服務(wù)的時候
- 5.1、根據(jù)consumeFeign2調(diào)用方法
- 5.2、使用SpringCloud請求標注(已經(jīng)實現(xiàn)了feign協(xié)議),直接去調(diào)用查找配置FeignConfiguration
- 5.3、因為要訪問Eureka,設(shè)置的有賬戶和密碼,在FeignConfiguration中配置賬戶和密碼