遠(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ò)的處理,可以知道熔斷的異常信息??梢宰远xfallbackFactory
:
@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-01Java編程常見(jiàn)內(nèi)存溢出異常與代碼示例
這篇文章主要介紹了Java編程常見(jiàn)內(nèi)存溢出異常與代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11