温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Feign怎么自定义注解翻译器

发布时间:2022-03-17 08:58:57 来源:亿速云 阅读:193 作者:iii 栏目:开发技术

本篇内容主要讲解“Feign怎么自定义注解翻译器”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“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;
    }

    到此,相信大家对“Feign怎么自定义注解翻译器”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI