Feign如何自定義注解翻譯器
更新時(shí)間:2022年03月16日 16:29:59 作者:chengqiuming
這篇文章主要介紹了Feign如何自定義注解翻譯器,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
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; ? //這個(gè)注解只能定義方法 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyUrl { ? ? //為注解配置兩個(gè)屬性 ? ? 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); ? ? } ? }
啟動服務(wù)類
測試
Hello World
Feign注解說明
Feign是常用的微服務(wù)rpc調(diào)用框架,下面對一些注解說明
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface FeignClient { /** * value和name的作用一樣,如果沒有配置url那么配置的值將作為服務(wù)名稱,用于服務(wù)發(fā)現(xiàn)。反之只是一個(gè)名稱。 * */ @AliasFor("name") String value() default ""; /** * serviceId已經(jīng)廢棄了,直接使用name即可。 */ /** @deprecated */ @Deprecated String serviceId() default ""; /** *某個(gè)服務(wù)提供的接口不止定義在一個(gè)類中,這樣啟動時(shí)會報(bào)Bean的名稱沖突。 * 解決方法: * 1:參數(shù)配置添加 * spring.main.allow-bean-definition-overriding=true * * 2:給每個(gè)client指定contextid * */ String contextId() default ""; /** * * 在注冊Feign Client Configuration的時(shí)候需要一個(gè)名稱,名稱是通過getClientName方法獲取的. * 查看源碼可知,如果配置了contextId就會用contextId, * 如果沒有配置就會去value,然后是name,最后是serviceId。 * 默認(rèn)都沒有配置,當(dāng)出現(xiàn)一個(gè)服務(wù)有多個(gè)Feign Client的時(shí)候就會報(bào)錯(cuò)了。 * * 其次的作用是在注冊FeignClient中,contextId會作為Client 別名的一部分,如果配置了qualifier優(yōu)先用qualifier作為別名。 * */ /** *見 value * */ @AliasFor("value") String name() default ""; /** * * 在注冊FeignClient中,指定client別名 * */ String qualifier() default ""; /** * * url用于配置指定服務(wù)的地址,相當(dāng)于直接請求這個(gè)服務(wù),不經(jīng)過Ribbon的服務(wù)選擇。像調(diào)試等場景可以使用。 * */ String url() default ""; /** * * 當(dāng)調(diào)用請求發(fā)生404錯(cuò)誤時(shí),decode404的值為true,那么會執(zhí)行decoder解碼,否則拋出異常。 * */ boolean decode404() default false; /** * * configuration是配置Feign配置類,在配置類中可以自定義Feign的Encoder、Decoder、LogLevel、Contract等。 * 具體查看FeignConfiguration類 * */ Class<?>[] configuration() default {}; /** * * 定義容錯(cuò)的處理類,也就是回退邏輯,fallback的類必須實(shí)現(xiàn)Feign Client的接口,無法知道熔斷的異常信息。 * * * * * 舉例: * //實(shí)現(xiàn)調(diào)用接口方法 * @Component * public class UserRemoteClientFallback implements UserRemoteClient { * @Override * public User getUser(int id) { * return new User(0, "默認(rèn)fallback"); * } * } * * //user服務(wù) * @FeignClient(value = "user", fallback = UserRemoteClientFallback.class) * public interface UserRemoteClient { * @GetMapping("/user/get") * public User getUser(@RequestParam("id")int id); * } * * */ Class<?> fallback() default void.class; /** * * 也是容錯(cuò)的處理,可以知道熔斷的異常信息。熔斷的另一種處理方法。 * * //服務(wù)類作為參數(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, "默認(rèn)"); * } * }; * } * } * */ Class<?> fallbackFactory() default void.class; /** * * path定義當(dāng)前FeignClient訪問接口時(shí)的統(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對應(yīng)的是@Primary注解,默認(rèn)為true. * 官方這樣設(shè)置也是有原因的。當(dāng)我們的Feign實(shí)現(xiàn)了fallback后,也就意味著Feign Client有多個(gè)相同的Bean在Spring容器中, * 當(dāng)我們在使用@Autowired(建議使用@Resource注入對象)進(jìn)行注入的時(shí)候,不知道注入哪個(gè),所以我們需要設(shè)置一個(gè)優(yōu)先級高的,@Primary注解就是干這件事情的。 * * */ boolean primary() default true; }
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
詳解在Spring MVC中使用注解的方式校驗(yàn)RequestParams
本篇文章主要介紹了詳解在Spring MVC中使用注解的方式校驗(yàn)RequestParams ,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03springboot2如何禁用自帶tomcat的session功能
這篇文章主要介紹了springboot2如何禁用自帶tomcat的session功能,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11SpringBoot實(shí)現(xiàn)WebSocket全雙工通信的項(xiàng)目實(shí)踐
本文主要介紹了SpringBoot實(shí)現(xiàn)WebSocket全雙工通信的項(xiàng)目實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05