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) {
        // 处理参数级别注解
        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那么配置的值将作为服务名称,用于服务发现。反之只是一个名称。
     *
     */
    @AliasFor("name")
    String value() default "";
    /**
     * serviceId已经废弃了,直接使用name即可。
     */
    /** @deprecated */
    @Deprecated
    String serviceId() default "";
    /**
     *某个服务提供的接口不止定义在一个类中,这样启动时会报Bean的名称冲突。
     * 解决方法:
     * 1:参数配置添加
     *  spring.main.allow-bean-definition-overriding=true
     *
     * 2:给每个client指定contextid
     *
     */
    String contextId() default "";
    /**
     *
     *  在注册Feign Client Configuration的时候需要一个名称,名称是通过getClientName方法获取的.
     *  查看源码可知,如果配置了contextId就会用contextId,
     *  如果没有配置就会去value,然后是name,最后是serviceId。
     *  默认都没有配置,当出现一个服务有多个Feign Client的时候就会报错了。
     *
     *  其次的作用是在注册FeignClient中,contextId会作为Client 别名的一部分,如果配置了qualifier优先用qualifier作为别名。
     *
     */
    /**
     *见 value
     *
     */
    @AliasFor("value")
    String name() default "";
    /**
     *
     * 在注册FeignClient中,指定client别名
     *
     */
    String qualifier() default "";
    /**
     *
     * url用于配置指定服务的地址,相当于直接请求这个服务,不经过Ribbon的服务选择。像调试等场景可以使用。
     *
     */
    String url() default "";
    /**
     *
     * 当调用请求发生404错误时,decode404的值为true,那么会执行decoder解码,否则抛出异常。
     *
     */
    boolean decode404() default false;
    /**
     *
     * configuration是配置Feign配置类,在配置类中可以自定义Feign的Encoder、Decoder、LogLevel、Contract等。
     * 具体查看FeignConfiguration类
     *
     */
    Class<?>[] configuration() default {};
    /**
     *
     * 定义容错的处理类,也就是回退逻辑,fallback的类必须实现Feign Client的接口,无法知道熔断的异常信息。
     *
     *
     *
     *
     * 举例:
     * //实现调用接口方法
     * @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;
    /**
     *
     * 也是容错的处理,可以知道熔断的异常信息。熔断的另一种处理方法。
     *
     * //服务类作为参数传入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, "默认");
     * 			}
     * 		};
     * 	}
     * }
     *
     */
    Class<?> fallbackFactory() default void.class;
    /**
     *
     * path定义当前FeignClient访问接口时的统一前缀
     * 比如接口地址是/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实现了fallback后,也就意味着Feign Client有多个相同的Bean在Spring容器中,
     *  当我们在使用@Autowired(建议使用@Resource注入对象)进行注入的时候,不知道注入哪个,所以我们需要设置一个优先级高的,@Primary注解就是干这件事情的。
     *
     *
     */
    boolean primary() default true;
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • springboot整合mqtt客户端示例分享

    springboot整合mqtt客户端示例分享

    这篇文章主要介绍了springboot整合mqtt客户端示例分享的相关资料,需要的朋友可以参考下
    2023-07-07
  • 使用springboot对linux进行操控的方法示例

    使用springboot对linux进行操控的方法示例

    这篇文章主要介绍了使用springboot对linux进行操控的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • Struts中使用validate()输入校验方法详解

    Struts中使用validate()输入校验方法详解

    这篇文章主要介绍了Struts中使用validate()输入校验方法,本文介绍的非常详细,具有参考借鉴价值,感兴趣的朋友一起看看吧
    2016-09-09
  • Java设计模式之策略模式原理与用法实例详解

    Java设计模式之策略模式原理与用法实例详解

    这篇文章主要介绍了Java设计模式之策略模式原理与用法,结合实例形式较为详细的分析了Java策略模式的概念、原理、定义及使用方法,并总结了相关的优缺点,具有一定参考借鉴价值,需要的朋友可以参考下
    2018-04-04
  • Java实现随机出题,10道10以内加减法计算代码实例

    Java实现随机出题,10道10以内加减法计算代码实例

    这篇文章主要介绍了Java实现随机出题,10道10以内加减法计算,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • Spring Hystrix熔断报警原理图例解析

    Spring Hystrix熔断报警原理图例解析

    这篇文章主要介绍了Spring Hystrix熔断报警原理图例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • 深入了解java-jwt生成与校验

    深入了解java-jwt生成与校验

    这篇文章主要介绍了深入了解java-jwt生成与校验,Json web token(JWT)是为了网络应用环境间传递声明而执行的一种基于JSON的开发标准(RFC 7519),该token被设计为紧凑且安全的,特别适用于分布式站点的单点登陆(SSO)场景。,需要的朋友可以参考下
    2019-06-06
  • SpringBoot2+Netty+WebSocket(netty实现websocket支持URL参数)问题记录

    SpringBoot2+Netty+WebSocket(netty实现websocket支持URL参数)问题记录

    Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架,这篇文章主要介绍了SpringBoot2+Netty+WebSocket(netty实现websocket,支持URL参数),需要的朋友可以参考下
    2023-12-12
  • Java多线程局域网聊天室的实现

    Java多线程局域网聊天室的实现

    在学习了一个学期的java以后,搞了一个多线程的聊天室,熟悉了一下服务器和客户机的操作。感兴趣的小伙伴们可以参考一下
    2021-06-06
  • shiro 认证流程操作

    shiro 认证流程操作

    这篇文章主要介绍了shiro 认证操作的相关资料,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-01-01

最新评论