Feign如何自定義注解翻譯器
更新時間:2022年03月16日 16:29:59 作者:chengqiuming
這篇文章主要介紹了Feign如何自定義注解翻譯器,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
Feign自定義注解翻譯器
新建自定義注解MyUrl
package org.crazyit.cloud.contract;?
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
?
//這個注解只能定義方法
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyUrl {
? ? //為注解配置兩個屬性
? ? String url();
? ? String method();
}新建接口,使用MyUrl注解
package org.crazyit.cloud.contract;?
public interface ContractClient {?
? ? @MyUrl(url = "/hello", method = "GET")
? ? public String hello();
}定義注解翻譯器
package org.crazyit.cloud.contract;?
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;?
import feign.Contract.BaseContract;
import feign.MethodMetadata;?
public class MyContract extends BaseContract {
?
? ? @Override
? ? protected void processAnnotationOnClass(MethodMetadata data, Class<?> clz) {
? ? ? ? // 處理類級別注解
? ? }
?
? ? @Override
? ? protected void processAnnotationOnMethod(MethodMetadata data,
? ? ? ? ? ? Annotation annotation, Method method) {
? ? ? ? // 注解是MyUrl類型的,才處理
? ? ? ? if(MyUrl.class.isInstance(annotation)) {
? ? ? ? ? ? MyUrl myUrl = method.getAnnotation(MyUrl.class);
? ? ? ? ? ? String url = myUrl.url();
? ? ? ? ? ? String httpMethod = myUrl.method();
? ? ? ? ? ? data.template().method(httpMethod);
? ? ? ? ? ? data.template().append(url);
? ? ? ? }
? ? }
?
? ? @Override
? ? protected boolean processAnnotationsOnParameter(MethodMetadata data,
? ? ? ? ? ? Annotation[] annotations, int paramIndex) {
? ? ? ? // 處理參數(shù)級別注解
? ? ? ? return false;
? ? }?
}測試類
package org.crazyit.cloud.contract;?
import org.crazyit.cloud.jaxrs.RsClient;?
import feign.Feign;
import feign.jaxrs.JAXRSContract;
?
public class ContractMain {?
? ? public static void main(String[] args) {
? ? ? ? ContractClient client = Feign.builder()
? ? ? ? ? ? ? ? .contract(new MyContract())
? ? ? ? ? ? ? ? .target(ContractClient.class,
? ? ? ? ? ? ? ? "http://localhost:8080");
? ? ? ? String result = client.hello();
? ? ? ? System.out.println(result);
? ? }
?
}啟動服務類
測試
Hello World
Feign注解說明
Feign是常用的微服務rpc調用框架,下面對一些注解說明
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface FeignClient {
/**
* value和name的作用一樣,如果沒有配置url那么配置的值將作為服務名稱,用于服務發(fā)現(xiàn)。反之只是一個名稱。
*
*/
@AliasFor("name")
String value() default "";
/**
* serviceId已經廢棄了,直接使用name即可。
*/
/** @deprecated */
@Deprecated
String serviceId() default "";
/**
*某個服務提供的接口不止定義在一個類中,這樣啟動時會報Bean的名稱沖突。
* 解決方法:
* 1:參數(shù)配置添加
* spring.main.allow-bean-definition-overriding=true
*
* 2:給每個client指定contextid
*
*/
String contextId() default "";
/**
*
* 在注冊Feign Client Configuration的時候需要一個名稱,名稱是通過getClientName方法獲取的.
* 查看源碼可知,如果配置了contextId就會用contextId,
* 如果沒有配置就會去value,然后是name,最后是serviceId。
* 默認都沒有配置,當出現(xiàn)一個服務有多個Feign Client的時候就會報錯了。
*
* 其次的作用是在注冊FeignClient中,contextId會作為Client 別名的一部分,如果配置了qualifier優(yōu)先用qualifier作為別名。
*
*/
/**
*見 value
*
*/
@AliasFor("value")
String name() default "";
/**
*
* 在注冊FeignClient中,指定client別名
*
*/
String qualifier() default "";
/**
*
* url用于配置指定服務的地址,相當于直接請求這個服務,不經過Ribbon的服務選擇。像調試等場景可以使用。
*
*/
String url() default "";
/**
*
* 當調用請求發(fā)生404錯誤時,decode404的值為true,那么會執(zhí)行decoder解碼,否則拋出異常。
*
*/
boolean decode404() default false;
/**
*
* configuration是配置Feign配置類,在配置類中可以自定義Feign的Encoder、Decoder、LogLevel、Contract等。
* 具體查看FeignConfiguration類
*
*/
Class<?>[] configuration() default {};
/**
*
* 定義容錯的處理類,也就是回退邏輯,fallback的類必須實現(xiàn)Feign Client的接口,無法知道熔斷的異常信息。
*
*
*
*
* 舉例:
* //實現(xiàn)調用接口方法
* @Component
* public class UserRemoteClientFallback implements UserRemoteClient {
* @Override
* public User getUser(int id) {
* return new User(0, "默認fallback");
* }
* }
*
* //user服務
* @FeignClient(value = "user", fallback = UserRemoteClientFallback.class)
* public interface UserRemoteClient {
* @GetMapping("/user/get")
* public User getUser(@RequestParam("id")int id);
* }
*
*
*/
Class<?> fallback() default void.class;
/**
*
* 也是容錯的處理,可以知道熔斷的異常信息。熔斷的另一種處理方法。
*
* //服務類作為參數(shù)傳入FallbackFactory模板參數(shù)
* @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, "默認");
* }
* };
* }
* }
*
*/
Class<?> fallbackFactory() default void.class;
/**
*
* path定義當前FeignClient訪問接口時的統(tǒng)一前綴
* 比如接口地址是/user/get, 如果你定義了前綴是user, 那么具體方法上的路徑就只需要寫/get 即可。
*
* @FeignClient(name = "user", path="user")
* public interface UserRemoteClient {
* @GetMapping("/get")
* public User getUser(@RequestParam("id") int id);
* }
*
*/
String path() default "";
/**
* primary對應的是@Primary注解,默認為true.
* 官方這樣設置也是有原因的。當我們的Feign實現(xiàn)了fallback后,也就意味著Feign Client有多個相同的Bean在Spring容器中,
* 當我們在使用@Autowired(建議使用@Resource注入對象)進行注入的時候,不知道注入哪個,所以我們需要設置一個優(yōu)先級高的,@Primary注解就是干這件事情的。
*
*
*/
boolean primary() default true;
}
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
SpringBoot2.X Kotlin系列之數(shù)據(jù)校驗和異常處理詳解
這篇文章主要介紹了SpringBoot 2.X Kotlin系列之數(shù)據(jù)校驗和異常處理詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-04-04
Spring Boot快速實現(xiàn) IP地址解析的示例詳解
這篇文章主要介紹了Spring Boot快速實現(xiàn)IP地址解析,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-08-08

