遠(yuǎn)程調(diào)用@FeignClient注解屬性使用詳解
正文
Feign是聲明性的web服務(wù)客戶端。它使編寫web服務(wù)客戶端更加容易。通過(guò)Feign我們可以實(shí)現(xiàn)調(diào)用遠(yuǎn)程服務(wù)像調(diào)用本地一樣便捷。本篇文章主要詳細(xì)聊聊Feign下的一個(gè)核心注解@FeignClient相關(guān)屬性。
通過(guò)查閱@FeignClient源碼,可以看到它的注解包括以下屬性:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FeignClient {
@AliasFor("name")
String value() default "";
/** @deprecated */
@Deprecated
String serviceId() default "";
String contextId() default "";
@AliasFor("value")
String name() default "";
String qualifier() default "";
String url() default "";
boolean decode404() default false;
Class<?>[] configuration() default {};
Class<?> fallback() default void.class;
Class<?> fallbackFactory() default void.class;
String path() default "";
boolean primary() default true;
}
name
定義當(dāng)前客戶端Client的名稱,等同于value屬性。
value
定義當(dāng)前客戶端Client的名稱,等同于name屬性。
serviceId
目前serviceId已經(jīng)廢棄了,直接使用name即可。
contextId
比如我們有個(gè)user服務(wù),但user服務(wù)中有很多個(gè)接口,我們不想將所有的調(diào)用接口都定義在一個(gè)類中,比如UserFeignClientA、UserFeignClentB,當(dāng)不同的Feign的name一致的時(shí)候,這時(shí)候Bean的名稱就會(huì)沖突,解決方式可以通過(guò)指定不同的contextId來(lái)解決問(wèn)題,舉個(gè)栗子:
UserFeignClientA
@FeignClient(name = "user.service", contextId = "userServiceA", url = "${user.service.url}", configuration = UserRemoteConfig.class)
public interface UserFeignClientA {
/**
* 獲取用戶默認(rèn)身份信息
*/
@RequestMapping("/user/identity/default")
ResultData<UserVisaIdentity> getDefaultIdentity(@RequestParam("userId") String userId);
}
UserFeignClientB
@FeignClient(name = "user.service", contextId = "userServiceB" url = "${user.service.url}", configuration = UserRemoteConfig.class)
public interface UserFeignClientB {
/**
* 新增大客戶信息
*/
@RequestMapping(value = {"/user/identity/saveIdentity"}, method = RequestMethod.POST)
ResultData<UserVisaIdentity> saveIdentity(@RequestBody UserVisaIdentity userVisaIdentity);
}
url
url用于配置指定服務(wù)的地址,相當(dāng)于直接請(qǐng)求這個(gè)服務(wù)。
path
@FeignClient(name = "template-service", url = "${universal.service.url}", path = "template", configuration = {RemoteErrorDecoder.class})
public interface ITemplateFeignService {
/**
* 多條件查詢
*
* @param templateSearchDto 多條件查詢
* @return 模板列表
*/
@GetMapping("/search")
ApiResult<PageResult<TemplateVo>> search(@Valid @SpringQueryMap TemplateSearchDto templateSearchDto);
}
path定義當(dāng)前FeignClient訪問(wèn)接口時(shí)的統(tǒng)一前綴,比如接口地址是/user/get, 如果你定義了前綴是user, 那么具體方法上的路徑就只需要寫/get 即可。上面將假設(shè)universal.service.url地址為 http://universal.com ,那么調(diào)用search請(qǐng)求地址為:universal.com/template/se…
configuration
configuration是配置Feign配置類,在配置類中可以自定義Feign的Encoder、Decoder、LogLevel、Contract等。
fallback
fallback定義容錯(cuò)的處理類,也就是回退邏輯,fallback的類必須實(shí)現(xiàn)Feign Client的接口,無(wú)法知道熔斷的異常信息。比如:
@FeignClient(name = "account-service")
public interface AccountServiceClient {
@RequestMapping(method = RequestMethod.GET, value = "/accounts/{accountName}", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, fallback = AccountServiceClientFallback.class)
String getAccount(@PathVariable("accountName") String accountName);
}
@Component
public class AccountServiceClientFallback implements AccountServiceClient {
private static final Logger LOGGER = LoggerFactory.getLogger(AccountServiceClientFallback.class);
@Override
public String getAccount(String accountName) {
LOGGER.error("Error during getAccount, accountName: {}", accountName);
}
}
fallbackFactory
也是容錯(cuò)的處理,可以知道熔斷的異常信息。可以自定義fallbackFactory:
@Component
public class UserRemoteClientFallbackFactory implements FallbackFactory<UserRemoteClient> {
private Logger logger = LoggerFactory.getLogger(UserRemoteClientFallbackFactory.class);
@Override
public UserRemoteClient create(Throwable cause) {
return new UserRemoteClient() {
@Override
public User getUser(int id) {
logger.error("UserRemoteClient.getUser異常", cause);
return new User(0, "默認(rèn)");
}
};
}
}
@FeignClient(value = "user-service", fallbackFactory = UserRemoteClientFallbackFactory.class)
public interface UserRemoteClient {
@GetMapping("/user/get")
public User getUser(@RequestParam("id") int id);
}
primary
primary對(duì)應(yīng)的是@Primary注解,默認(rèn)為true,官方這樣設(shè)置也是有原因的。當(dāng)我們的Feign實(shí)現(xiàn)了fallback后,也就意味著FeignClient有多個(gè)相同的Bean在Spring容器中,當(dāng)我們?cè)谑褂?code>@Autowired進(jìn)行注入的時(shí)候,不知道注入哪個(gè),所以我們需要設(shè)置一個(gè)優(yōu)先級(jí)高的,@Primary注解就是干這件事情的。
qualifier
qualifier對(duì)應(yīng)的是@Qualifier注解,使用場(chǎng)景跟上面的primary關(guān)系很淡,一般場(chǎng)景直接@Autowired直接注入就可以了。
如果我們的Feign Client有fallback實(shí)現(xiàn),默認(rèn)@FeignClient注解的primary=true, 意味著我們使用@Autowired注入是沒(méi)有問(wèn)題的,會(huì)優(yōu)先注入你的FeignClient。
如果你把primary設(shè)置成false了,直接用@Autowired注入的地方就會(huì)報(bào)錯(cuò),不知道要注入哪個(gè)對(duì)象。
解決方案很明顯,你可以將primary設(shè)置成true即可,如果由于某些特殊原因,你必須得去掉primary=true的設(shè)置,這種情況下我們?cè)趺催M(jìn)行注入,我們可以配置一個(gè)qualifier,然后使用@Qualifier注解進(jìn)行注入,示列如下:
@FeignClient(name = "optimization-user", path="user", qualifier="userRemoteClient")
public interface UserRemoteClient {
@GetMapping("/get")
public User getUser(@RequestParam("id") int id);
}
Feign Client注入
@Autowired
@Qualifier("userRemoteClient")
private UserRemoteClient userRemoteClient;
好了,以上就是@FeignClient注解相關(guān)屬性說(shuō)明。
以上就是遠(yuǎn)程調(diào)用@FeignClient注解屬性使用詳解的詳細(xì)內(nèi)容,更多關(guān)于@FeignClient 遠(yuǎn)程調(diào)用的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用Spring MVC實(shí)現(xiàn)雙向數(shù)據(jù)綁定
Spring MVC是一個(gè)廣泛用于構(gòu)建Java Web應(yīng)用程序的框架,它提供了眾多功能,包括雙向數(shù)據(jù)綁定,在這篇文章中,我們將向Java新手介紹如何使用Spring MVC實(shí)現(xiàn)雙向數(shù)據(jù)綁定,以及為什么這個(gè)特性如此重要,需要的朋友可以參考下2024-01-01
Java編程常見(jiàn)內(nèi)存溢出異常與代碼示例
這篇文章主要介紹了Java編程常見(jiàn)內(nèi)存溢出異常與代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11

